Saturday, January 25, 2014

A Sample Program

Now that we have a web server and PHP installed, the next step is to install Symfony2 and NetBeans. However, I decided to take an excursion here and familiarize myself a little bit with the syntax of PHP. For this purpose, instead of digging through books or tutorials, I will work on simple exercises to learn the workings of this language.

Here is the first program that I will be working on:

Write a program which receives input from 10 drop-down lists, where the possible values are integers between 0 and 9, inclusive. The values should be stored in an indexed array. After the numbers are collected from the user, the contents of the array should be displayed on a new page and the user should be presented with a choice between sorting the values, calculating the average of the values or starting over.
I will give a step by step explanation of the program as I write it.
  • Step 1: Write the HTML code for the user interface.

    The first step is to design the user interface. I begin by creating a single drop-down list with a single option:

    <html>
    <body>
        Element 1: <select name="e1">
            <option value="0">
                0
            </option>
        </select>
    </body>
    </html>
    

    Name this file "array.php" and save to the root folder of the server. Mine is c:\inetpub\wwwroot. This generates the following output:

    Next, I will use a for loop to add the remaining options:

    <html>
    <body>
        Element 1: <select name="e1">
            <?php
            for ($n = 0; $n < 10; $n++)
            {
                echo "<option value=\"$n\">$n</option>";
            }
            ?>
        </select>
    </body>
    </html>
    

    Now, we have a drop down menu with 10 options:

    Finally, I will enclose the whole thing in another for loop to generate 10 of these drop-down boxes:

    <html>
    <body>
        <?php
        for ($m = 1; $m <= 10; $m++)
        {
            echo "Element $m: <select name=\"e$m\">";
            for ($n = 0; $n < 10; $n++)
            {
                echo "<option value=\"$n\">$n</option>";
            }
            echo "</select>&nbsp;&nbsp;";
        }
        ?>
    </body>
    </html>
    

    Enclosing the option boxes with a <form> element and adding the "Submit" and "Reset" buttons conclude the user interface design:

    <html>
    <body>
        <form action="array2.php" method="post">
            <?php
            for ($m = 1; $m <= 10; $m++)
            {
                echo "Element $m: <select name=\"e$m\">";
                for ($n = 0; $n < 10; $n++)
                {
                    echo "<option value=\"$n\">$n</option>";
                }
                echo "</select>&nbsp;&nbsp;";
            }
            ?>
            <input type="submit"> <input type="reset">
        </form>
    </body>
    </html>
    

    The result is the following:

    This is not the best looking design but it will do.

  • Step 2: Create an array and pass the user input to the array.

    I begin with a simple HTML code:

    <html>
    <body>
        Your Numbers:
    </body>
    </html>
    

    I name this file "array2.php" and save. Next, I create an indexed array with the values from the previous page. I assign the value of the <select> element with name "e1" to the first element of this array. Let also display this element to see if everything is okay:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            $numbers[0] = $_POST["e1"];
        }
        ?>
        Your Numbers: <?php echo $numbers[0]; ?>
    </body>
    </html>
    

    When we choose a number for the first element from the previous page and click "Submit", the result is as follows:

    This is exactly what I wanted to see. So, I create a for loop to assign all the values from the page to the array:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            for ($i = 1; $i <= 10; $i++)
            {
                $numbers[$i - 1] = $_POST["e$i"];
            }
        }
    
        echo "Your Numbers: ".implode(", ",$numbers)."<br/>";
        ?>
    </body>
    </html>
    

    It is time to choose random values and test the output:

  • Step 3: Perform the sorting and averaging options.

    In this step, I will sort the array and find the average values and display the result. I will give the user a choice between the two later. I am simply going to copy the for loop I have previously written to display the elements of the sorted array the way I like:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            for ($i = 1; $i <= 10; $i++)
            {
                $numbers[$i - 1] = $_POST["e$i"];
            }
        }
        echo "Your Numbers: ".implode(", ",$numbers)."<br/>";
        sort($numbers);
        echo "Sorted Array: ".implode(", ",$numbers)."<br/>";
        echo "Average: " . array_sum($numbers) / count($numbers);
        ?>
    </body>
    </html>
    

    The result is the following:

  • Step 4: Add radio buttons and a submit button to perform the selected task.

    It is time to add radio buttons to this page to give the user the option to either sort or find the average of the array. I will comment out the sort and average calculations for the time being:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            for ($i = 1; $i <= 10; $i++)
            {
                $numbers[$i - 1] = $_POST["e$i"];
            }
        }
        echo "Your Numbers: ".implode(", ",$numbers)."<br/>";
        ?>
        
        <form>
            <input name="choice" type="radio" value="sort" checked>Sort these
            numbers&nbsp;&nbsp; 
            <input name="choice" type="radio" value="average">Find the 
            average of these numbers
        </form>
        <!--
        sort($numbers);
        echo "Sorted Array: ".implode(", ",$numbers)."<br/>";
        echo "Average: " . array_sum($numbers) / count($numbers);
        ?>
        -->
    </body>
    </html>
    

    This renders as follows:

    Next, let us add a button to perform the selected operation and another button to start over:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            for ($i = 1; $i <= 10; $i++)
            {
                $numbers[$i - 1] = $_POST["e$i"];
            }
        }
        echo "Your Numbers: ".implode(", ",$numbers)."<br/>";
        ?>
    
        <form style="display:inline;"> 
            <input checked name="choice" type="radio" value="sort">Sort these 
            numbers&nbsp;&nbsp; 
            <input name="choice" type="radio" value="average">Find the 
            average of these numbers<br/><br/>
            <input type="submit" value="Go!">
        </form>
        <form action="array.php" method="post" style="display:inline;">
            <input type="submit" value="Start Over">
        </form>
    
        <!--
        sort($numbers);
        echo "Sorted Array: ".implode(", ",$numbers)."<br/>";
        echo "Average: " . array_sum($numbers) / count($numbers);
        ?>
        -->
    </body>
    </html>
    

    Currently, the "Start Over" button takes us back to the first page while the "Go!" button just throws a bunch of "Undefined offset" notices. At this point, the screen output is the following:

  • Step 5: Modify the code to display the results on the same page.

    I decided to reload the array2.php file to display the results, so I have to change the code accordingly. First thing to do is to create another if statement withing the one which checks if the REQUEST_METHOD is POST. This one will use the array_key_exists function to check if the user is coming from the previous page or the same (there is probably a better way to do this, but I don't want to spend a lot of time to find out):

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            if (array_key_exists("e1", $_POST))
            {
                for ($i = 1; $i <= 10; $i++)
                {
                    $numbers[$i - 1] = $_POST["e$i"];
                }
            }
            elseif (array_key_exists("choice", $_POST))
            {
            }
            else
            {
                echo "Unknown error.<br/>";
            }
        }
        echo "Your Numbers: " . implode(", ", $numbers) . "<br/>";
        ?>
    
        <form style="display:inline;">
            <input checked name="choice" type="radio" value="sort">Sort these
            numbers&nbsp;&nbsp; 
            <input name="choice" type="radio" value=
            "average">Find the average of these numbers<br/><br/>
            <input type="submit" value="Go!">
        </form>
    
        <form action="array.php" method="post" style="display:inline;">
            <input type="submit" value="Start Over">
        </form>
        <!--
        sort($numbers);
        echo "Sorted Array: ".implode(", ",$numbers)."<br/>";
        echo "Average: " . array_sum($numbers) / count($numbers);
        ?>
        -->
    </body>
    </html>
    

    Next, I introduce a string variable (named $action) which will contain the code for the the buttons if the user is coming from array.php and will contain the appropriate result if the user has pressed the "Go!" button:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            if (array_key_exists("e1", $_POST))
            {
                for ($i = 1; $i <= 10; $i++)
                {
                    $numbers[$i - 1] = $_POST["e$i"];
                }
                $action = "<form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\" 
                          method=\"post\" style=\"display:inline;\">
                          <input checked name=\"choice\" type=\"radio\" value=\"sort\">Sort these
                          numbers&nbsp;&nbsp; 
                          <input name=\"choice\" type=\"radio\" value=
                          \"average\">Find the average of these numbers<br/><br/>
                          <input type=\"submit\" value=\"Go!\">
                          </form>";
            }
            elseif (array_key_exists("choice", $_POST))
            {
            }
            else
            {
                echo "Unknown error.<br/>";
            }
        }
        echo "Your Numbers: " . implode(", ", $numbers) . "<br/>";
        echo $action;
        ?>
    
        <form action="array.php" method="post" style="display:inline;">
            <input type="submit" value="Start Over">
        </form>
        <!--
        sort($numbers);
        echo "Sorted Array: ".implode(", ",$numbers)."<br/>";
        echo "Average: " . array_sum($numbers) / count($numbers);
        ?>
        -->
    </body>
    </html>
    

    As it can be observed at the 14th line of this code, $_SERVER["PHP_SELF"]) is passed for the action to be performed upon submission. This variable stores the name of the file on which the current script is running. For security reasons, this variable must pass through htmlspecialchars().

    The next thing to do is to decide what the program should do if the user presses the "Go!" button. The first thing to do is to check whether the user wants to sort the array or get the average value. If choice is sort, then sort the array and display the result. If choice is average, then simply display the average. If choice is null, which means the user did not make the choice yet, then serialize() the array $numbers and submit it via POST:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            if (array_key_exists("e1", $_POST))
            {
                for ($i = 1; $i <= 10; $i++)
                {
                    $numbers[$i - 1] = $_POST["e$i"];
                }
                $action = "<form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\" 
                           method=\"post\" style=\"display:inline;\">
                          <input checked name=\"choice\" type=\"radio\" value=\"sort\">Sort these
                           numbers&nbsp;&nbsp; 
                          <input name=\"choice\" type=\"radio\" value=
                          \"average\">Find the average of these numbers<br/><br/>
                          <input type =\"hidden\" name=\"params\" value=\"" . htmlspecialchars(serialize($numbers)) . "\">
                          <input type=\"submit\" value=\"Go!\">
                          </form>";
            }
            elseif (array_key_exists("choice", $_POST))
            {
                $numbers = unserialize($_POST["params"]);
                if ($_POST["choice"] == "sort")
                {
                    sort($numbers);
                    $action = "Sorted Array: " . implode(", ", $numbers) . "<br/>";
                }
                elseif ($_POST["choice"] == "average")
                {
                    $action = "Average: " . array_sum($numbers) / count($numbers) . "<br/>";
                }
                else
                {
                    $action = "<form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\"style=\"display:inline;\" method=\"post\">
                                <input checked name=\"choice\" type=\"radio\" value=\"sort\">Sort these numbers&nbsp;&nbsp;
                                <input name=\"choice\" type=\"radio\" value=\"average\">Find the average of these numbers
                                <br/><br/>
                                <input type =\"hidden\" name=\"params\" value=\"" . htmlspecialchars(serialize($numbers)) . "\">
                                <input type =\"submit\" value=\"Go!\"></form>\n";
                }
            }
            else
            {
                echo "Unknown error.<br/>";
            }
        }
        echo "Your Numbers: " . implode(", ", $numbers) . "<br/>";
        echo $action;
        ?>
    
        <form action="array.php" method="post" style="display:inline;">
            <input type="submit" value="Start Over">
        </form>
    </body>
    </html>
    

    The output is as follows:

    At this point, the program is capable of displaying the selected result; but I will take an additional step to add a "Back" button so that the user can choose a different operation. Also, I will introduce a $result variable to store the sorted array so that the program does not change the original array entered by the user.

  • Step 6: Finalize the program.

    Adding a "Back" button and making some cosmetic changes, the final code for array2.php is as follows:

    <html>
    <body>
        <?php
        $numbers = array();
    
        if ($_SERVER["REQUEST_METHOD"] == "POST")
        {
            if (array_key_exists("e1", $_POST))
            {
                for ($i = 1; $i <= 10; $i++)
                {
                    $numbers[$i - 1] = $_POST["e$i"];
                }
                $action = "<form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\" 
                          method=\"post\" style=\"display:inline;\">
                          <input checked name=\"choice\" type=\"radio\" value=\"sort\">Sort these
                          numbers&nbsp;&nbsp; 
                          <input name=\"choice\" type=\"radio\" value=
                          \"average\">Find the average of these numbers<br/><br/>
                         <input type =\"hidden\" name=\"params\" value=\"" . htmlspecialchars(serialize($numbers)) . "\">
                         <input type=\"submit\" value=\"Go!\">
                         </form>";
            }
            elseif (array_key_exists("choice", $_POST))
            {
                $numbers = unserialize($_POST["params"]);
                if ($_POST["choice"] == "sort")
                {
                    $result = $numbers;
                    sort($result);
                    $action = "Sorted Array: " . implode(", ", $result) . "<br/><br/>
                               <form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\"style=\"display:inline;\" method=\"post\">
                               <input type =\"hidden\" name=\"params\" value=\"" . htmlspecialchars(serialize($numbers)) . "\">
                               <input type =\"hidden\" name=\"choice\" value=\"null\"> 
                               <input type =\"submit\" value=\"Back\"></form>\n";
                }
                elseif ($_POST["choice"] == "average")
                {
                    $action = "Average: " . array_sum($numbers) / count($numbers) . "<br/><br/>
                              <form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\"style=\"display:inline;\" method=\"post\">
                              <input type =\"hidden\" name=\"params\" value=\"" . htmlspecialchars(serialize($numbers)) . "\">
                              <input type =\"hidden\" name=\"choice\" value=\"null\"> 
                              <input type =\"submit\" value=\"Back\"></form>\n";
                }
                else
                {
                    $action = "<form action=\"" . htmlspecialchars($_SERVER["PHP_SELF"]) . "\"style=\"display:inline;\" method=\"post\">
                              <input checked name=\"choice\" type=\"radio\" value=\"sort\">Sort these numbers&nbsp;&nbsp;
                              <input name=\"choice\" type=\"radio\" value=\"average\">Find the average of these numbers
                              <br/><br/>
                              <input type =\"hidden\" name=\"params\" value=\"" . htmlspecialchars(serialize($numbers)) . "\">
                              <input type =\"submit\" value=\"Go!\"></form>\n";
                }
            }
            else
            {
                echo "Unknown error.<br/>";
            }
        }
        echo "Your Numbers: " . implode(", ", $numbers) . "<br/><br/>";
        echo $action;
        ?>
    
        <form action="array.php" method="post" style="display:inline;">
            <input type="submit" value="Start Over">
        </form>
    </body>
    </html>
    

    Here's the output:

No comments :

Post a Comment