Jump to content
Larry Ullman's Book Forums

Christopher

Members
  • Posts

    52
  • Joined

  • Last visited

  • Days Won

    1

Posts posted by Christopher

  1. Larry and all,

    If you could take a look at my solution and correct me if any mistake, I would be much appreciated.

     

    1. Change the delete_user.php and edit_user.php pages so that they both display the user being affected in the browser window’s title bar.

     

    Made the change in Header.html:

     

    <!DOCTYPE html>
    <html lang="en">
    <head>
        <meta charset="utf-8">
        <title><?php echo $page_title . '(' . $_GET['ln'] . ' ' . $_GET['fn'] . ')'; ?></title>
        <link rel="stylesheet" href="includes/style.css" type="text/css">
    </head>

     

    Then both delete and edit scripts can reflect user's name in browser windows's title bar. One question is for the $_POST case(the form is submitted, and there's no $GET[] value), should we handle it also? If so then I guess I need to write a conditional here in Header.html.

     

     

    2. Modify edit_user.php so that you can also change a user’s password.
    3. If you’re up for a challenge, modify edit_user.php so that the form elements’ values come from $_POST, if set, and the database if not.

     

    <?php # Script 10.3 - edit_user.php - PURSUE
    // This page is for editing a user record.
    // This page is accessed through view_users.php.

    $page_title = 'Edit a User';
    include ('includes/header.html');
    echo '<h1>Edit a User</h1>';

    // Check for a valid user ID, through GET or POST:
    if ( (isset($_GET['id'])) && (is_numeric($_GET['id'])) ) { // From view_users.php
        $id = $_GET['id'];
    } elseif ( (isset($_POST['id'])) && (is_numeric($_POST['id'])) ) { // Form submission.
        $id = $_POST['id'];
    } else { // No valid ID, kill the script.
        echo '<p class="error">This page has been accessed in error.</p>';
        include ('includes/footer.html');
        exit();
    }

    require ('./mysqli_connect.php');

    // Check if the form has been submitted:
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

        $errors = array();
        
        // Check for a first name:
        if (empty($_POST['first_name'])) {
            $errors[] = 'You forgot to enter your first name.';
        } else {
            $fn = mysqli_real_escape_string($dbc, trim($_POST['first_name']));
        }
        
        // Check for a last name:
        if (empty($_POST['last_name'])) {
            $errors[] = 'You forgot to enter your last name.';
        } else {
            $ln = mysqli_real_escape_string($dbc, trim($_POST['last_name']));
        }

        // Check for an email address:
        if (empty($_POST['email'])) {
            $errors[] = 'You forgot to enter your email address.';
        } else {
            $e = mysqli_real_escape_string($dbc, trim($_POST['email']));
        }
        
        // PURSUE 2 - Check for a NEW password(updated) and match against the confirmed password:
            //If these values are submitted, update the password in the database as well. If these inputs are left blank, do not update the password in the database.(do not put an error message in $errors[] & use the original $q)

        if (!empty($_POST['pass1'])) {
            if ($_POST['pass1'] != $_POST['pass2']) {
                $errors[] = 'Your new password did not match the confirmed password.';
            } else {
                $np = mysqli_real_escape_string($dbc, trim($_POST['pass1']));
            }
        } // if pass1 is empty, then do nothing here, delete the original else statement. But nend to add judge it again in the below query($q)
            
        if (empty($errors)) { // If everything's OK.
        
            //  Test for unique email address:
            $q = "SELECT user_id FROM users WHERE email='$e' AND user_id != $id";
            $r = @mysqli_query($dbc, $q);
            if (mysqli_num_rows($r) == 0) { // Not find it, so the email address is unique

                // Make the query to UPDATE the table:
                // PURSUE 2 - add pass=SHA1('$np')
               if (!empty($_POST['pass1'])) {

                 $q = "UPDATE users SET first_name='$fn', last_name='$ln', email='$e', pass=SHA1('$np') WHERE user_id=$id LIMIT 1";
               } else { // if no pass1 input, then not update the password in the database
               $q = "UPDATE users SET first_name='$fn', last_name='$ln', email='$e' WHERE user_id=$id LIMIT 1";                                 
               }

                                                                                                 
                $r = @mysqli_query ($dbc, $q);
                if (mysqli_affected_rows($dbc == 1) { // If it ran OK.

                    // Print a message:
                    echo '<p>The user has been edited.</p>';    
                    
                } else { // If it did not run OK.
                    echo '<p class="error">The user could not be edited due to a system error. We apologize for any inconvenience.</p>'; // Public message.
                    echo '<p>' . mysqli_error($dbc) . '<br />Query: ' . $q . '</p>'; // Debugging message.
                }
                    
            } else { // Already registered.
                echo '<p class="error">The email address has already been registered.</p>';
            }
            
        } else { // Report the errors.

            echo '<p class="error">The following error(s) occurred:<br />';
            foreach ($errors as $msg) { // Print each error.
                echo " - $msg<br />\n";
            }
            echo '</p><p>Please try again.</p>';
        
        } // End of if (empty($errors)) IF.

    } // End of submit conditional.

    // Always show the form...

    // Retrieve the user's information:
    $q = "SELECT first_name, last_name, email FROM users WHERE user_id=$id";        
    $r = @mysqli_query ($dbc, $q);

    if (mysqli_num_rows($r) == 1) { // Valid user ID, show the form.

          // Get the user's information:
          $row = mysqli_fetch_array ($r, MYSQLI_NUM);

          // PURSUE 3 - form elements’ values come from $_POST, if set, and the database if not
          // Note: if UPDATE check is passed/UPDATE is succeful, then $row[] has the same value as $_POST[]
          $form_fn = isset($_POST['first_name']) ? $_POST['first_name'] : $row[0];
          $form_ln = isset($_POST['last_name']) ? $_POST['last_name'] : $row[1];
          $form_email = isset($_POST['email']) ? $_POST['email'] : $row[2];


          // Create the form:
          // PURSUE 2 - also change a user’s password, adding the new password input and a confirmation
          // PURSUE 3 - substitute original $row[0], $row[1], $row[2] with $form_fn...

          echo '<form action="edit_user.php" method="post">
    <p>First Name: <input type="text" name="first_name" size="15" maxlength="15" value="' . $form_fn . '" /></p>
    <p>Last Name: <input type="text" name="last_name" size="15" maxlength="30" value="' . $form_ln . '" /></p>
    <p>Email Address: <input type="text" name="email" size="20" maxlength="60" value="' . $form_email . '"  /></p>
    <p>New Password: <input type="password" name="pass1" size="10" maxlength="20" value="" ></p>
    <p>Confirm Password: <input type="password" name="pass2" size="10" maxlength="20" value="" ></p>

    <p><input type="submit" name="submit" value="Submit" /></p>
    <input type="hidden" name="id" value="' . $id . '" />
    </form>';

    } else { // Not a valid user ID. If no record was returned from the database, because an invalid user ID was
                   // submitted, this message is displayed:
        echo '<p class="error">This page has been accessed in error.</p>';
    }

    //mysqli_close($dbc);
            
    include ('includes/footer.html');
    ?>

     

     

    4. Change the value of the $display variable in view_users.php to alter the pagination.

     

    This one is easy, in view_user.php, just modify the constant value:

     

    <?php # Script 10.5 - #5
    // This script retrieves all the records from the users table.
    // This new version allows the results to be sorted in different ways.

    $page_title = 'View the Current Users';
    include ('includes/header.html');
    echo '<h1>Registered Users</h1>';

    require ('./mysqli_connect.php');

    // Number of records to show per page:
    $display = 23;

     

     

     

  2. Larry,

     

    Thanks for the reply. I am learning C# because it's easier than C++, and C++ today is losing its ground in the IT industry. Also I will focus on C#, coz it's actually a modern version of Java.

     

    What I'd do with C# is mainly two things:

    1. Since I have being learning PHP(your book), JS(your book), CSS & HTML, I can later also use ASP.NET to create websites. And many concepts and skills that I learned from PHP suite will also serve ASP.NET;

    2. I want to develop some mobile apps for iOS and Android, using C# Mono, because I am interested in mobile development too.

    3. Because I love playing video games, in the future I might take a look at the game engine Unity 3d, which use C# or JS to develop.

     

    Just feel that JS is becoming increasingly powerful, not a web font-end language anymore, but a general purpose script language.

  3. When I use NetBeans to debug scripts of Ch10, I encountered some strange issues:

     

    1.   Script 10.2 - delete_user.php

     

    The code block  in this script:

    // Check if the form has been submitted:
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        
            if ($_POST['sure'] == 'Yes') { // Delete the record.
        
                // Make the query:
                $q = "DELETE FROM users WHERE user_id=$id LIMIT 1";        
                $r = @mysqli_query ($dbc, $q);
                if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.  
    

    When I use NetBeans to debug this script, after the record is deleted($r = @mysqli_query ($dbc, $q) is executed), the affected_rows = 1 in the variable section of NetBeans, which is correct. But then after I press F7 to step into and 'if (mysqli_affected_rows($dbc) == 1)' is executed, affected_rows suddenly becomes -1, and the program logic jumps to the error reporting branch.

    If I don't debug and just run the script, the Deletion is totally OK. What's the possible cause?

    Here's the whole script:

            <?php # Script 10.2 - delete_user.php
        // This page is for deleting a user record.
        // This page is accessed through view_users.php.
        
        $page_title = 'Delete a User';
        include ('includes/header.html');
        echo '<h1>Delete a User</h1>';
        
        // Check for a valid user ID, through GET or POST:
        if ( (isset($_GET['id'])) && (is_numeric($_GET['id'])) ) { // From view_users.php
            $id = $_GET['id'];
        } elseif ( (isset($_POST['id'])) && (is_numeric($_POST['id'])) ) { // Form submission.
            $id = $_POST['id'];
        } else { // No valid ID, kill the script.
            echo '<p class="error">This page has been accessed in error.</p>';
            include ('includes/footer.html'); 
            exit();
        }
        
        require ('./mysqli_connect.php');
        
        // Check if the form has been submitted:
        if ($_SERVER['REQUEST_METHOD'] == 'POST') {
        
            if ($_POST['sure'] == 'Yes') { // Delete the record.
        
                // Make the query:
                $q = "DELETE FROM users WHERE user_id=$id LIMIT 1";        
                $r = @mysqli_query ($dbc, $q);
                if (mysqli_affected_rows($dbc) == 1) { // If it ran OK.
        
                    // Print a message:
                    echo '<p>The user has been deleted.</p>';    
        
                } else { // If the query did not run OK.
                    echo '<p class="error">The user could not be deleted due to a system error.</p>'; // Public message.
                    echo '<p>' . mysqli_error($dbc) . '<br />Query: ' . $q . '</p>'; // Debugging message.
                }
            
            } else { // No confirmation of deletion.
                echo '<p>The user has NOT been deleted.</p>';    
            }
        
        } else { // Show the form, to confirm that this user should be deleted.
        
            // Retrieve the user's information:
            $q = "SELECT CONCAT(last_name, ', ', first_name) FROM users WHERE user_id=$id";
            $r = @mysqli_query ($dbc, $q);
        
            if (mysqli_num_rows($r) == 1) { // Valid user ID, show the form. (Just 1 result as user_id is PK)
        
                // Get the user's information:
                $row = mysqli_fetch_array ($r, MYSQLI_NUM);
                
                // Display the record being deleted:
                echo "<h3>Name: $row[0]</h3>
                Are you sure you want to delete this user?";
                
                // Create the form:
                echo '<form action="delete_user.php" method="post">
            <input type="radio" name="sure" value="Yes" /> Yes 
            <input type="radio" name="sure" value="No" checked="checked" /> No
            <input type="submit" name="submit" value="Submit" />
            <input type="hidden" name="id" value="' . $id . '" />
            </form>';
            
            } else { // Not a valid user ID.
                echo '<p class="error">This page has been accessed in error.</p>';
            }
        
        } // End of the main submission conditional.
        
        mysqli_close($dbc);
                
        include ('includes/footer.html');
        ?>
    

    2. Another problem is that after finish debugging the script, there are many lines of warnings:

    Warning: main(): Couldn't fetch mysqli in C:\xampp\htdocs\phpmysql4_working\delete_user.php on line 75
        
         Warning: main(): Couldn't fetch mysqli in C:\xampp\htdocs\phpmysql4_working\includes\footer.html on line 11
        Call Stack
        #    Time    Memory    Function    Location
        1    0.1000    146128    {main}( )    ..\delete_user.php:0
        2    249.5054    187032    include( 'C:\xampp\htdocs\phpmysql4_working\includes\footer.html' )    ..\delete_user.php:75  
    

    But MySQL was actually been accessed successfully.

     

     

    3. Script 10.4 - view_users.php #4

    // This script retrieves all the records from the users table.
    // This new version paginates the query results

     

    The problem here is similar to question 2 above: If I directly run the script, the result in the browser is good. But if I debug it, after debug finishes, there are many lines of error messages like:

    Warning: main(): Couldn't fetch mysqli_result in C:\xampp\htdocs\phpmysql4_working\view_users_pagination.php on line 80
    Call Stack
    #	Time	Memory	Function	Location
    1	0.1090	146936	{main}( )	..\view_users_pagination.php:0
    
    ( ! ) Warning: main(): Couldn't fetch mysqli_result in C:\xampp\htdocs\phpmysql4_working\view_users_pagination.php on line 80
    Call Stack
    #	Time	Memory	Function	Location
    1	0.1090	146936	{main}( )	..\view_users_pagination.php:0
    

    Anyone met this kind of issue during debugging?

  4. Hi all,

     

    If you could take a look at my solution and correct me if any mistake, I would be much appreciated.

     

    1. Change the use of mysqli_num_rows( ) in view_users.php so that it’s only called if the query had a TRUE result.

     

    <?php # Script 9.6 - view_users.php #2 - PURSUE
    #Change the use of mysqli_num_rows( )in view_users.php so that it’s only called #if the query had a TRUE result.

    // This script retrieves all the records from the users table.

    $page_title = 'View the Current Users';
    include ('includes/header.html');

    // Page header:
    echo '<h1>Registered Users</h1>';

    require ('./mysqli_connect.php'); // Connect to the db.
            
    // Make the query:
    $q = "SELECT CONCAT(last_name, ', ', first_name) AS name, DATE_FORMAT(registration_date, '%M %d, %Y') AS dr FROM users ORDER BY registration_date ASC";        
    $r = @mysqli_query ($dbc, $q); // Run the query.

    if($r) { // PURSUE - mysqli_num_rows( ) is only called when the query has a TRUE result
          // Count the number of returned rows:
          $num = mysqli_num_rows($r);

          if ($num > 0) { // If it ran OK, display the records.

                  // Print how many users there are:
                  echo "<p>There are currently $num registered users.</p>\n";

                  // Table header.
                  echo '<table align="center" cellspacing="3" cellpadding="3" width="75%">
                  <tr><td align="left"><b>Name</b></td><td align="left"><b>Date Registered</b></td></tr>
          ';

                  // Fetch and print all the records:
                  while ($row = mysqli_fetch_array($r, MYSQLI_ASSOC)) {
                          echo '<tr><td align="left">' . $row['name'] . '</td><td align="left">' . $row['dr'] . '</td></tr>
                          ';
                  }

                  echo '</table>'; // Close the table.

                  mysqli_free_result ($r); // Free up the resources.    

          } else { // If no records were returned.

                  echo '<p class="error">There are currently no registered users.</p>';

          }
    } else { // Handle the situation that the query has no correct result
          // Public message:
          echo '<p class="error">The query was incorrect. We apologize for any inconvenience.</p>';

          // Debugging message:
          echo '<p>' . mysqli_error($dbc) . '<br /><br />Query: ' . $q . '</p>';
    }


    mysqli_close($dbc); // Close the database connection.

    include ('includes/footer.html');
    ?>

     

     

     

    ----------

    1. Apply the mysqli_num_rows( ) function to register.php, as suggested in an earlier sidebar.
    2. Apply the mysqli_affected_rows( ) function to register.php to confirm that the INSERT worked.

     

    <?php # Script 9.5 - register.php #2 - PURSUE
    #1. Apply the mysqli_num_rows( ) function to register.php to prevent someone from registering with
    #   the same email address multiple times
    #2. Apply the mysqli_affected_rows( )function to register.php to confirm that the INSERT worked.

    // This script performs an INSERT query to add a record to the users table.

    $page_title = 'Register';
    include ('includes/header.html');

    // Check for form submission:
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

        require ('./mysqli_connect.php'); // Connect to the db.  
            
        $errors = array(); // Initialize an error array.
        
        // Check for a first name:
        if (empty($_POST['first_name'])) {
            $errors[] = 'You forgot to enter your first name.';
        } else {
            $fn = mysqli_real_escape_string($dbc, trim($_POST['first_name']));
        }
        
        // Check for a last name:
        if (empty($_POST['last_name'])) {
            $errors[] = 'You forgot to enter your last name.';
        } else {
            $ln = mysqli_real_escape_string($dbc, trim($_POST['last_name']));
        }
        
        // Check for an email address:
        if (empty($_POST['email'])) {
            $errors[] = 'You forgot to enter your email address.';
        } else { // User entered email address
               $e = mysqli_real_escape_string($dbc, trim($_POST['email']));
               $q = "SELECT user_id FROM users WHERE email = '$e'";
    // PURSUE 1 - confirm the email address isn’t currently registered.
               $r = @mysqli_query($dbc, $q);
               $num = mysqli_num_rows($r);  
               if ($num != 0) { // Result table is NOT empty, meaning the email address already existed
              $errors[] = 'This email address has already been registered.'; // Add error message to $errors so INSERT won't happen later     

               }                                                     
        }

                    
        // Check for a password and match against the confirmed password:
        if (!empty($_POST['pass1'])) {
            if ($_POST['pass1'] != $_POST['pass2']) {
                $errors[] = 'Your password did not match the confirmed password.';
            } else {
                $p = mysqli_real_escape_string($dbc, trim($_POST['pass1']));
            }
        } else {
            $errors[] = 'You forgot to enter your password.';
        }
        
        if (empty($errors)) { // If everything's OK.
        
            // Register the user in the database...
            
            // Make the query:
            $q = "INSERT INTO users (first_name, last_name, email, pass, registration_date) VALUES ('$fn', '$ln', '$e', SHA1('$p'), NOW() )";        
            $r = @mysqli_query ($dbc, $q); // Run the query.
            //if ($r) { // If it ran OK.
            if (mysqli_affected_rows($dbc) == 1) { // PURSUE 2 - If the INSERT worked

                            
                // Print a message:
                echo '<h1>Thank you!</h1>
            <p>You are now registered. In Chapter 12 you will actually be able to log in!</p><p><br /></p>';    
            
            } else { // If INSERT did not run OK.
                
                // Public message:
                echo '<h1>System Error</h1>
                <p class="error">You could not be registered due to a system error. We apologize for any inconvenience.</p>';
                
                // Debugging message:
                echo '<p>' . mysqli_error($dbc) . '<br /><br />Query: ' . $q . '</p>';
                            
            } // End of if ($r) IF.
            
            mysqli_close($dbc); // Close the database connection.

            // Include the footer and quit the script:
            include ('includes/footer.html');
            exit();
            
        } else { // Report the errors.
        
            echo '<h1>Error!</h1>
            <p class="error">The following error(s) occurred:<br />';
            foreach ($errors as $msg) { // Print each error.
                echo " - $msg<br />\n";
            }
            echo '</p><p>Please try again.</p><p><br /></p>';
            
        } // End of if (empty($errors)) IF.
        
        mysqli_close($dbc); // Close the database connection. NEW, to match the open in the begining of the conditional

    } // End of the main Submit conditional.
    ?>
    <h1>Register</h1>
    <form action="" method="post">
        <p>First Name: <input type="text" name="first_name" size="15" maxlength="20" value="<?php if (isset($_POST['first_name'])) echo $_POST['first_name']; ?>" /></p>
        <p>Last Name: <input type="text" name="last_name" size="15" maxlength="40" value="<?php if (isset($_POST['last_name'])) echo $_POST['last_name']; ?>" /></p>
        <p>Email Address: <input type="text" name="email" size="20" maxlength="60" value="<?php if (isset($_POST['email'])) echo $_POST['email']; ?>"  /> </p>
        <p>Password: <input type="password" name="pass1" size="10" maxlength="20" value="<?php if (isset($_POST['pass1'])) echo $_POST['pass1']; ?>"  /></p>
        <p>Confirm Password: <input type="password" name="pass2" size="10" maxlength="20" value="<?php if (isset($_POST['pass2'])) echo $_POST['pass2']; ?>"  /></p>
        <p><input type="submit" name="submit" value="Register" /></p>
    </form>
    <?php include ('includes/footer.html'); ?>

     

     

     

  5. Thanks Larry, I got it; that way these two variables $days and $days_modulus:

        $days = $hours / 24;
        $days_modulus = $days % 24;

    are not needed, which makes the code concise.

     

    I moved them into the 'else' conditional:

     

        } else {  // $hours > 24
          echo '<h1>Total Estimated Cost</h1>
        <p>The total cost of driving ' . $_POST['distance'] . ' miles, averaging ' . $_POST['efficiency'] . ' miles per gallon,
              and paying an average of $' . $_POST['gallon_price'] . ' per gallon, is $' . $cost . '. If you drive at
              an average of ' . $_POST['average_speed'] . ' miles per hour, the trip will take
              approximately ' . number_format( $hours / 24, 2) . ' days and ' . ($hours / 24) % 24 . ' hours.</p>';

     

     

    -------------

     

    Here is the updated full script:

     

    <?php
    # Script 3.10 - calculator.php #5 - Pursue
    # 1. Change calculator.php so that it uses a constant in lieu of the hard-coded average speed of 65.
    # 2. Better yet, modify calculator.php so that the user can enter the average speed or select it from a list
    # of options.
    # 3. Update the output of calculator.php so that it displays the number of days and hours the trip will take,
    # when the number of hours is greater than 24.
    # 4. As a more advanced trick, rewrite calculator.php so that the create_radio( ) function call is only in
    #  the script once, but still creates three radio buttons. Hint: Use a loop.
    #
    #
    // This function creates a radio button.
    // The function takes two arguments: the value and the name.
    // The function also makes the button "sticky".
    function create_radio($value, $name = 'gallon_price') {

      // Start the element:
      echo '<input type="radio" name="' . $name . '" value="' . $value . '"';

      // Check for stickiness:
      if (isset($_POST[$name]) && ($_POST[$name] == $value)) {
        echo ' checked="checked"';
      }

      // Complete the element:
      echo " /> $value ";
    }

    // End of create_radio() function.
    // This function calculates the cost of the trip.
    // The function takes three arguments: the distance, the fuel efficiency, and the price per gallon.
    // The function returns the total cost.
    function calculate_trip_cost($miles, $mpg, $ppg) {

      // Get the number of gallons:
      $gallons = $miles / $mpg;

      // Get the cost of those gallons:
      $dollars = $gallons * $ppg;

      // Return the formatted cost:
      return number_format($dollars, 2);
    }

    // End of calculate_trip_cost() function.

    $page_title = 'Trip Cost Calculator';
    include ('includes/header.html');

    // PURSUE 1 - Define the constant for average speed:
    define ('AVERAGE_SPEED', 65);

    // Check for form submission:
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

      // Minimal form validation:
      if (isset($_POST['distance'], $_POST['gallon_price'], $_POST['efficiency'], $_POST['average_speed']) &&
              is_numeric($_POST['distance']) && is_numeric($_POST['gallon_price']) && is_numeric($_POST['efficiency']) && is_numeric($_POST['average_speed'])) {

        // Calculate the results:
        $cost = calculate_trip_cost($_POST['distance'], $_POST['efficiency'], $_POST['gallon_price']);
    //$hours = $_POST['distance'] / AVERAGE_SPEED;
        $hours = $_POST['distance'] / $_POST['average_speed'];
       
        // PURSUE 3 - Output displays the number of days and hours the trip will take
        if ( $hours <= 24) {
        echo '<h1>Total Estimated Cost</h1>
        <p>The total cost of driving ' . $_POST['distance'] . ' miles, averaging ' . $_POST['efficiency'] . ' miles per gallon,
              and paying an average of $' . $_POST['gallon_price'] . ' per gallon, is $' . $cost . '. If you drive at
              an average of ' . $_POST['average_speed'] . ' miles per hour, the trip will take
              approximately ' . number_format($hours, 2) . ' hours.</p>';
        } else {  // $hours > 24
          echo '<h1>Total Estimated Cost</h1>
        <p>The total cost of driving ' . $_POST['distance'] . ' miles, averaging ' . $_POST['efficiency'] . ' miles per gallon,
              and paying an average of $' . $_POST['gallon_price'] . ' per gallon, is $' . $cost . '. If you drive at
              an average of ' . $_POST['average_speed'] . ' miles per hour, the trip will take
              approximately ' . number_format( $hours / 24, 2) . ' days and ' . ($hours / 24) % 24 . ' hours.</p>';
          
        }
      } else { // Invalid submitted values.
        echo '<h1>Error!</h1>
            <p class="error">Please enter a valid distance, price per gallon, fuel efficiency and average speed.</p>';
      }
    } // End of main submission IF.
    // Leave the PHP section and create the HTML form:
    ?>

    <h1>Trip Cost Calculator</h1>
    <form action="" method="post">
      <p>Distance (in miles): <input type="text" name="distance" value="<?php if (isset($_POST['distance'])) echo $_POST['distance']; ?>" /></p>
      <p>Ave. Price Per Gallon: <span class="input">
    <?php
    // PURSUE 4 - the create_radio( ) function call is only in the script once
    // Step 1: create an array to hold the three/four/... radio button values:

    $radio_values = array('3.00', '3.50', '4.00', '5.00');

    // Step 2: use a foreach loop to loop through the array:
    foreach ($radio_values as $radio_value) {
        create_radio($radio_value);
    }
    //create_radio('3.00');
    //create_radio('3.50');
    //create_radio('4.00');
    ?>
        </span></p>
      <p>Fuel Efficiency: <select name="efficiency">
          <option value="10"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '10')) echo ' selected="selected"'; ?>>Terrible</option>
          <option value="20"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '20')) echo ' selected="selected"'; ?>>Decent</option>
          <option value="30"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '30')) echo ' selected="selected"'; ?>>Very Good</option>
          <option value="50"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '50')) echo ' selected="selected"'; ?>>Outstanding</option>
        </select></p>
    <!-- // PURSUE 2 - Let user enter average speed: (Select from a list of options is not implemented here) -->     
      <p>Average Speed: <input type="text" name="average_speed" value="<?php if (isset($_POST['average_speed'])) echo $_POST['average_speed']; ?>"></p>
      <p><input type="submit" name="submit" value="Calculate!" /></p>
    </form>

    <?php include ('includes/footer.html'); ?>

    • Like 1
  6. Guys,

     

    I want to get a better understanding of OOP, and start to learn C#(especially the OO part). I guess learning C# or Java will lay a solid foundation for OOP, after that if I want to use OOP in PHP, it would be much easier.

     

    the modern history of OOP is C++ --> Java --->C#, these are the main languages for implement the idea of OOP, so I plan on choosing C#. (At the same, of course, I could read PHP OO and do some coding exercises.)

     

    Any suggestions?

  7. Hi All,

    Here is my solution to Pursue exercises in CH3. I combined 4 questions into one script. If you could take a look at my code and correct if I am wrong, I would be reaaaaly appreciated!

     

    Here are the questions on the book:

     

    # 1. Change calculator.php so that it uses a constant in lieu of the hard-coded average speed of 65.
    # 2. Better yet, modify calculator.php so that the user can enter the average speed or select it from a list
    # of options.
    # 3. Update the output of calculator.php so that it displays the number of days and hours the trip will take, when the number of hours is greater than 24.
    # 4. As a more advanced trick, rewrite calculator.php so that the create_radio( ) function call is only in
    #  the script once, but still creates three radio buttons. Hint: Use a loop.

     

     

    Here is my solution script: ( I highlighted the code for the solution )

     

    <?php
    # Script 3.10 - calculator.php #5 - Pursue
    # 1. Change calculator.php so that it uses a constant in lieu of the hard-coded average speed of 65.
    # 2. Better yet, modify calculator.php so that the user can enter the average speed or select it from a list
    # of options.
    # 3. Update the output of calculator.php so that it displays the number of days and hours the trip will take,
    # when the number of hours is greater than 24.
    # 4. As a more advanced trick, rewrite calculator.php so that the create_radio( ) function call is only in
    #  the script once, but still creates three radio buttons. Hint: Use a loop.
    #
    #
    // This function creates a radio button.
    // The function takes two arguments: the value and the name.
    // The function also makes the button "sticky".
    function create_radio($value, $name = 'gallon_price') {

      // Start the element:
      echo '<input type="radio" name="' . $name . '" value="' . $value . '"';

      // Check for stickiness:
      if (isset($_POST[$name]) && ($_POST[$name] == $value)) {
        echo ' checked="checked"';
      }

      // Complete the element:
      echo " /> $value ";
    }

    // End of create_radio() function.
    // This function calculates the cost of the trip.
    // The function takes three arguments: the distance, the fuel efficiency, and the price per gallon.
    // The function returns the total cost.
    function calculate_trip_cost($miles, $mpg, $ppg) {

      // Get the number of gallons:
      $gallons = $miles / $mpg;

      // Get the cost of those gallons:
      $dollars = $gallons * $ppg;

      // Return the formatted cost:
      return number_format($dollars, 2);
    }

    // End of calculate_trip_cost() function.

    $page_title = 'Trip Cost Calculator';
    include ('includes/header.html');

    // PURSUE 1 - Define the constant for average speed:
    define ('AVERAGE_SPEED', 65);

    // Check for form submission:
    if ($_SERVER['REQUEST_METHOD'] == 'POST') {

      // Minimal form validation:
      if (isset($_POST['distance'], $_POST['gallon_price'], $_POST['efficiency'], $_POST['average_speed']) &&
              is_numeric($_POST['distance']) && is_numeric($_POST['gallon_price']) && is_numeric($_POST['efficiency']) && is_numeric($_POST['average_speed'])) {

        // Calculate the results:
        $cost = calculate_trip_cost($_POST['distance'], $_POST['efficiency'], $_POST['gallon_price']);
    //$hours = $_POST['distance'] / AVERAGE_SPEED;
        $hours = $_POST['distance'] / $_POST['average_speed'];
        
        // PURSUE 3 - Calculate days and modulus
        $days = $hours / 24;
        $days_modulus = $days % 24;

        // PURSUE 3 - Print the results, using Days and Hours
        if ( $hours <= 24) {
        echo '<h1>Total Estimated Cost</h1>
        <p>The total cost of driving ' . $_POST['distance'] . ' miles, averaging ' . $_POST['efficiency'] . ' miles per gallon,
              and paying an average of $' . $_POST['gallon_price'] . ' per gallon, is $' . $cost . '. If you drive at
              an average of ' . $_POST['average_speed'] . ' miles per hour, the trip will take
              approximately ' . number_format($hours, 2) . ' hours.</p>';
        } else {
          echo '<h1>Total Estimated Cost</h1>
        <p>The total cost of driving ' . $_POST['distance'] . ' miles, averaging ' . $_POST['efficiency'] . ' miles per gallon,
              and paying an average of $' . $_POST['gallon_price'] . ' per gallon, is $' . $cost . '. If you drive at
              an average of ' . $_POST['average_speed'] . ' miles per hour, the trip will take
              approximately ' . number_format($days, 2) . ' days and ' . $days_modulus . ' hours.</p>';
          
        }
      } else { // Invalid submitted values.
        echo '<h1>Error!</h1>
            <p class="error">Please enter a valid distance, price per gallon, fuel efficiency and average speed.</p>';
      }
    } // End of main submission IF.
    // Leave the PHP section and create the HTML form:
    ?>

    <h1>Trip Cost Calculator</h1>
    <form action="" method="post">
      <p>Distance (in miles): <input type="text" name="distance" value="<?php if (isset($_POST['distance'])) echo $_POST['distance']; ?>" /></p>
      <p>Ave. Price Per Gallon: <span class="input">
    <?php
    // PURSUE 4  the create_radio( ) function call is only in the script once
    // Step 1: create an array to hole the three radio button values:
    $radio_values = array('3.00', '3.50', '4.00', '5.00');

    // Step 2: use a foreach loop to loop through the array:
    foreach ($radio_values as $radio_value) {
        create_radio($radio_value);
    }
    //create_radio('3.00');
    //create_radio('3.50');
    //create_radio('4.00');
    ?>
        </span></p>
      <p>Fuel Efficiency: <select name="efficiency">
          <option value="10"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '10')) echo ' selected="selected"'; ?>>Terrible</option>
          <option value="20"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '20')) echo ' selected="selected"'; ?>>Decent</option>
          <option value="30"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '30')) echo ' selected="selected"'; ?>>Very Good</option>
          <option value="50"<?php if (isset($_POST['efficiency']) && ($_POST['efficiency'] == '50')) echo ' selected="selected"'; ?>>Outstanding</option>
        </select></p>
    <!-- // PURSUE 2 - Let user enter average speed: (Select from a list of options is not implemented here) -->     
      <p>Average Speed: <input type="text" name="average_speed" value="<?php if (isset($_POST['average_speed'])) echo $_POST['average_speed']; ?>"></p>
      <p><input type="submit" name="submit" value="Calculate!" /></p>
    </form>

    <?php include ('includes/footer.html'); ?>

     

    • Like 1
  8. Another issue caused by this is that the result on P90 displays not very neat in the browser (Total Estimated Cost is also floated.)

     

     

    To fix it, I added a class .result for it:

         // Print the results:
            echo '<h1 class="result">Total Estimated Cost</h1>
        <p>The total cost of driving ' . $_POST['distance'] . ' miles, averaging ' . $_POST['efficiency'] . ' miles per gallon, and paying an average of $' . $_POST['gallon_price'] . ' per

     

     

    .result {
      clear: left;
    }

     

    After that, the result shows ok in the browser.

    I wanted to paste screenshots here but found image extensions are not allowed.

  9. Larry,

     

    I think the css file for CH3 needs to add one rule to clear the float of the 'navigation' div, otherwise in the browser the first h1 of the content div is also floated:

     

    /* navigation */
    #navigation {
        background:#fafafa;
        border-right:1px solid #999;
        margin:0 auto;
        width:750px;
        height:40px;
        list-style:none;
    }
    #navigation li {
        border-left:1px solid #999;
        float:left;
        width:149px;
        list-style:none;
    }
    #navigation a {
        color:#555;
        display:block;
        line-height:40px;
        text-align:center;
    }
    #navigation a:hover {
        background:#e3e3e3;
        color:#555;
    }
    #navigation .active {
        background:#e3e3e3;
        color:#777;
    }

    /* content */
    #content {
    clear: left; /* should clear float */
        height:auto;
        margin:0 auto;
        padding:0 0 20px;
        width:751px;
    }

  10. Just wonder is there a book on the whole phases of dynamic website development? There are so many books on HTML/CSS, JavaScript, PHP, ASP.NET, etc, but each is just part of the whole web development circle. If there was a book introducing:

    1. How to analyze business requirements and design the structure of a specific dynamic website(eg. page layout, architecture...);

    2. How to code PHP to implement some functionalists on the web pages;

    3. How to use MySQL to implement database;

    4. How to code JavaScript to implement some functionalists;

    5. How to publish the website onto the Internet;

    6. How to manage the whole web development phases....

     

    then it would be great!

  11. Just wonder is there a book on the whole phases of dynamic website development? There are so many books on HTML/CSS, JavaScript, PHP, ASP.NET, etc, but each is just part of the whole web development circle. If there was a book introducing:

    1. How to analyze business requirements and design the structure of a specific dynamic website(eg. page layout, architecture...);

    2. How to code PHP to implement some functionalists on the web pages;

    3. How to use MySQL to implement database;

    4. How to code JavaScript to implement some functionalists;

    5. How to publish the website onto the Internet;

    6. How to manage the whole web development phases....

     

    then it would be great!

     

     

     

     

  12.  

    To create and call your own function:

    1. Open today.js in your text editor or IDE.

    2. Begin defining a new function:

    // This function is used to update the text of an HTML element.

    // The function takes two arguments: the element’s ID and the

    text message.

    function setText(elementId, message) {

    ‘use strict’;

     

    In the book, the '//' is not printed in front of 'text message.'

     

  13. Ch6, P198, at the bottom of the page:

     

    for (var i = 0; i < myList.length; i++) {
    // Do something with myList.
    }
    The first time the loop is encountered, the i variable is set to 0: the first possible
    indexed position. The condition then checks if i is less than the length property
    of the array. While that condition is TRUE, the loop’s body can do something with
    myList: myList[0], myList[1], and so forth. Then i is incremented. Once i
    equals the length of the array, the loop is terminated, as there is no element indexed
    at myList[length].

     

    "as there is no element indexed at myList[length]."

    I think a more accurate description would be "as there is no element indexed at myList[myList.length]."

     

     

  14.     <form action="" method="post" id="theForm">
            <fieldset><legend>Create Your Membership</legend>
                <p>Complete this form to calculate your membership. There's a 20% discount if you enroll for more than one year!</p>
    			<div><label for="type">Type</label><select name="type" id="type" required>
    			    <option value="basic">Basic - $10.00</option>
    			    <option value="premium">Premium - $15.00</option>
    			    <option value="gold">Gold - $20.00</option>
    			    <option value="platinum">Platinum - $25.00</option>
    			</select></div>
    			<div><label for="years">Years</label><input type="number" name="years" id="years" min="1" required></div>
    			<div><label for="cost">Cost</label><input type="text" name="cost" id="cost" disabled></div>
    			<input type="submit" value="Calculate" id="submit">
            </fieldset>
        </form>
    

    I think the required attribute in this select element may not be correct. Netbeans indicates this is an error, and I checked online:

     

    http://dev.w3.org/html5/spec-author-view/the-select-element.html#the-select-element

    When there is no default option, a placeholder can be used instead:
    
    <select name="unittype" required>
     <option value=""> Select unit type </option>
     <option value="1"> Miner </option>
     <option value="2"> Puffer </option>
     <option value="3"> Snipey </option>
     <option value="4"> Max </option>
     <option value="5"> Firebot </option>
    </select>
    
    

    seems if required is used, then the first option's value should be empty.

  15. Larry, thanks for your advice. Though the fact is a little disappointing, I plan to do the follow things:

    1. I will create a website myself, using HTML5, JavaScript, PHP & MySQL, from scratch.

    2. I will keep an eye on some PHP part-time job to gain experience, and ask round my friends and family if they have such demands.

    3. I start to prepare for the Zend PHP certification exam while learning PHP by reading your book. Also for Javascript & HTML5, I plan to take Microsoft's relative certification.

     

    I worked in IT industry for many years, but the technologies I used to do is way different from web development, so I'm basically a newbie in web development. But I want some change in my life and I want to become a web developer. I know this will not be easy for me(maybe it's easy for a java developer to learn PHP or JavaScript), but I still want to give it a shot, and if I got any progress I will update it on the forum.

  16. I am trying to do my best, to learn PHP through Larry's book; also I am reading another PHP book named Murach's PHP and MySQL. I love this language and all web-related technologies.

     

    How can I get some real PHP project experiences? Coz I want to get a job as a web developer. Maybe to check some opportunities on freelance.com? Or just send my resume to those job ads and see if I can get an interview?(but I have no real PHP experience yet...)

     

    Also I think one important way to learning each programming language is to study good source code. What are some nice PHP source code that are suitable for studying? Some suggested to read the source code of WordPress or Zend Framework.

  17. Larry,

     

    in CH10, P303:

     

    $url = 'page.php?name=' . urlencode
    ➝ ('Elliott Smith');
    You only need to do this when programmatically
    adding values to a URL. When a form
    uses the GET method, it automatically encodes
    the data.

     

    // Actually I think it should be the POST method, coz  unlike GET request, POST data does not need to be encoded or decoded.

     

     

    P304:

     

    In the preceding example, a new version
    of the view_users.php script was written.
    This one now includes links to the edit_
    user.php and delete_user.php pages,
    passing each a user’s ID through the URL.

     

    // I think this 'a' is a typo here(not needed).

  18. Larry,

     

    There is one line missing here on the book(the downloaded code has it):

    // If everything is OK, print the message:
    if ($name && $email && $gender && $comments) {
    
    	echo "<p>Thank you, <b>$name</b>, for the following comments:<br />
    	<tt>$comments</tt></p>
    	<p>We will reply to you at <i>$email</i>.</p>\n";
    	
    	echo $greeting;
    

    echo $greeting;   is missing on the book(P50)

  19. Larry,

     

    In the HTML form of this chapter:

            <p><label for="gender">Gender: </label>
                <input type="radio" name="gender" value="M"> Male 
                <input type="radio" name="gender" value="F"> Female</p>
    

    I read a book on HTML5, and it says the for="gender" in <label> should refer to the id of the table control, but there is no 'id' in these two <input> tags. I created my HTML5 script in Netbeans when reading this chapter, and noticed Netbeans shows message on this for="gender":

    The "for" attribute of the "label" element must refer to a form control.
    From line 23, column 12; to line 23, column 31
    (Rule Category: All Other)

     

    So Is this way of coding XHTML style only?

  20. I checked some information online these two days, and here are some of my findings:

    1. HTML5+JS development for mobile apps has one limitation at the moment: speed(as Hartley mentioned), compared with mobiles' native languages(Java, Objective-C, etc)

    2. HTML5+JS has been used in MS windows 8 apps, and I think this will be a trend. MS also lanuched its MCSD certification for using HTML5+JS to development windows apps. (I am going to take the exams after finishing this book).

     

    Though there are some limitations at the moment, I guess HTML5+JS will be used more and more in the future. So, I am going to go back and read Modern JavaScript now :)

×
×
  • Create New...