9. Increasing Functionality

What We Will Cover


Elucidations

Homework Questions?

Quiz Questions?

Questions from last class?

9.1. Functions

Learner Outcomes

At the end of the lesson the student will be able to:

  • Write code to pass values to functions
  • Write code to return a value from a function
  • Describe identifier scope
  • Code their own functions

9.1.1: About Functions

Function -- a subprogram (method, procedure or subroutine) that executes a block of code when called.

  • Like most other programming languages, PHP lets you group a block of code into a module called a function
  • When your program wants to execute the block of code, it calls the function
  • Writing a function makes it easier to reuse that block of code
  • If you call the function many times, you write potentially shorter scripts
  • By writing functions, you can organize your code into logical groups
  • Organizing code into logical groups makes program development more manageable

Using Functions

  • Functions are invoked (used) to perform a task with a function call
  • The syntax of a function call:
    functionName(arguments);
    
  • Where functionName is the name of the function and arguments are values to send to the function
  • Some functions return a result to the calling function (caller)
  • Functions are like a boss (calling function) asking a worker (called function) to complete a task

Example Function Calls

$value = pow(2, 3);  // $value gets 8
print_r($value);     // no return value
$value = sqrt(49);   // $value gets 7
var_dump($value);    // no return value

9.1.2: Predefined Functions

  • PHP offers a multitude of libraries containing predefined functions
  • For a complete list: Function Reference
  • Some of those commonly used for Web applications are listed below
  • Some database function libraries are listed as well
  • We have discussed some of the libraries and will discuss more during the course
  • You should always use predefined functions when they are available

Some Commonly-Used Function Libraries

Library Description
Arrays For interacting with and manipulating arrays.
BC Math For arbitrary precision mathematics with numbers of any size and precision represented as strings.
Date/Time For getting the date and time from the server.
Java For interacting with Java on the server.
Mail For sending email.
Math For mathematical operations not provided by operators (see lesson 6.2.7).
Misc. For functions that do not fit into other categories such as die(), eval(), highlight_file() and sleep().
Output Control For controlling when output is sent from the script.
PHP Options/Info For getting information about PHP itself.
Program Execution For executing commands on the operating system of the server.
Pspell For checking the spelling of a word and offering suggestions.
PCRE For using Perl-compatible regular expressions.
Regexps For using POSIX extended regular expressions.
Session For saving some data across multiple page accesses.
Strings For manipulating strings (see lesson 7.1).
URLs For dealing with URL strings.
Variables For testing and manipulating variables.
Zip For reading ZIP compressed archives and the files inside them.
Zlib For reading and writing gzip (.gz) compressed files.

Some DataBase Function Libraries

Library Description
dba For accessing Berkeley DB style databases.
dBase For accessing records stored in dBase-format (dbf) databases.
dbx A database abstraction layer for accessing all supported databases using a single calling convention.
COM For accessing COM objects on Windows platforms, including MS Access databases.
FrontBase For accessing FrontBase database servers.
filePro For read-only access to data stored in filePro databases.
Informix For accessing Informix (IDS) 7.x, SE 7.x, Universal Server (IUS) 9.x and IDS 2000.
Firebird/InterBase For accessing InterBase databases put out by Borland/Inprise.
Ingres For accessing Ingres II database servers.
MS SQL Server For accessing MS SQL Server databases.
mSQL For accessing mSQL database servers.
MySQL For accessing MySQL database servers.
MySQLi For accessing MySQL database servers version 4.1 and above.
OCI8 For accessing Oracle8 and Oracle7 databases using the Oracle8 Call-Interface (OCI8).
ODBC For accessing database for which you have ODBC driver.
Ovrimos For accessing Ovrimos SQL Server databases.
PostgreSQL For accessing PostgreSQL database servers.
SQLite For accessing the SQLite Embeddable SQL Database Engine.
Sybase For accessing Sybase database servers.

9.1.3: Writing Functions

  • While PHP has many predefined functions, we can write our own as well
  • The syntax for defining a function is:
    function functionName(parameters) {
        PHP commands
    }
    
  • Where the functionName is a name that the programmer chooses and parameters are values accepted by the function
  • Parameters are optional and you include them only if you want to accept an argument
  • Commands executed by the function are enclosed in curly braces {...}, which is called the function body
  • Notice how the syntax is implemented in the following example

Example PHP Function

<?php
// Function definition
function add($num1$num2) {
    
$sum $num1 $num2;
    return 
$sum;
}

$calc add(34); // function call returns 7
echo "The sum is: $calc";
?>

Try it!

Function Definition

  • The name of the function comes after the keyword function:
    function add($num1, $num2) {...}
  • Technically, you can use any valid identifier for a function name
  • However, you should use a name that suggests the action the function performs
  • Also, the normal style is to start function names with a lower case letter
  • After the name is the parenthesis which contain the parameters, if any
  • The body of the function first adds two numbers together:
    $sum = $num1 + $num2;
    
  • The last statement returns the calculation to the function call:
    return $sum;
  • When you return a value, you must save it in order to use it:
    $calc = add(3, 4);
    echo "The sum is: $calc";
    
  • If you just want to save the value and just print it, then you can write something like:
    echo "The sum is: ".add(3, 4);
    
  • In the following exercise and sections we explore creating functions in more detail
  • Also, notice that PHP ignores the function until the function call

Exercise 9.1

In this exercise we explore how to write a function in PHP.

Specifications

  1. Open the XAMPP Control Panel by double-clicking the icon on the desktop or by using the Apache Friends entry in the start menu.

    XAMPP icon

  2. Start the Apache and MySQL modules, if they are not already running.

    XAMPP control panel

  3. Start TextPad, or another text editor, and enter this starter code:
    <html>
    <head>
    <title>Echo Request</title>
    </head>
    
    <body>
    <h2>Echo Request</h2>
    <pre>
    <? var_dump($_REQUEST) ?>
    </pre>
    </body>
    </html>
    

    Save this code in a file named echo.php to the htdocs directory and phptest subdirectory of your Apache (XAMPP) installation (htdocs/phptest). This simple echo script is useful when debugging forms as a target for the action attribute.

  4. Save the following starter code in a file named funselect.php to the htdocs directory and phptest subdirectory of your Apache (XAMPP) installation (htdocs/phptest).
    <html>
    <head><title>Selection Function</title></head>
    <body>
    <h1>Selection Function</h1>
    <form action="echo.php" method="GET">
    <p>Select one:
    <?
    // Enter PHP code here
    
    ?>
    </p>
    <p><input type="submit" value="Submit"></p>
    </form>
    </body>
    </html>
    

    We will use this code to create a function that builds selection lists.

  5. Open a new Web browser tab or window and enter localhost/phptest/funselect.php in the address field.

    You should see a page like the following in the browser:

  6. First let us add a function that builds a selection list. Add the following code between the PHP tags of your funselect.php file:
    function makeSelect() {
        $name = "fruits";
        echo "<select name=\"$name\">\n";
        $list = array("Apples", "Bananas", "Cherries");
        foreach ($list as $key=>$value) {
            echo "<option value=\"$key\">";
            echo $value;
            echo "</option>\n";
        }
        echo "</select>";
    }
    
    This function will build a selection list. Notice that functions in PHP:
    1. Start with the word function
    2. Followed by a name that you make up
    3. Followed by parenthesis ( )

    Also note that PHP ignores the function until you call it. Even if your reload (refresh) your page, you will not see the selection list.

  7. Add a function call either before or after the function definition like:
    makeSelect();  // call the function
    

    Reload (refresh) your page and verify you see a selection list like the following in the browser:

  8. One of the main reason to use functions is to let us reuse code without having to rewrite it. Thus, we want our selection function to build many different selection lists. The first thing we want to do is move the $name and $list variables outside the function, like:
    $name = "fruits";
    $list = array("Apples", "Bananas", "Cherries");
    makeSelect();  // call the function
    
    function makeSelect() {
        echo "<select name=\"$name\">\n";
        foreach ($list as $key=>$value) {
            echo "<option value=\"$key\">";
            echo $value;
            echo "</option>\n";
        }
        echo "</select>";
    }
    

    However, when we make this change and reload (refresh) the page, we do not see the selection list. This is because the $name and $list variables outside the function are in a different scope than the $name and $list variables inside the function. For more information see section 9.1.4: Scope.

  9. The best way to correct the problem is to pass the $name and $list variables to the function as arguments. Change your function call to:
    makeSelect($name, $list);

    The $name and $list variables are now arguments to the function. However an argument needs a parameter to "catch" the value the function call passes. For this we need change the first line of our function to:

    function makeSelect($name, $list) {
    

    Now when we reload (refresh) our page, we see the function call passes the $name and $list variables to the makeSelect() function parameters and we see a correct selection list. For more information see section 9.1.5: Arguments and Parameters.

  10. Now that we have written a reusable function, we can create multiple selection lists. For example, add the following code to make two selection lists:
    $name = "fruits";
    $list = array("Apples", "Bananas", "Cherries");
    makeSelect($name, $list);
    
    $name = "states";
    $list = array("California", "Oregon", "Washington");
    makeSelect($name, $list);
    
  11. Sometimes we want functions to return values. For instance, PHP math functions return values so we can use the returned value in a calculation. We can change our function to return a value by making the following changes to the function definition:
    function makeSelect($name, $list) {
        $returnVal = "<select name=\"$name\">\n";
        foreach ($list as $key=>$value) {
            $returnVal .= "<option value=\"$key\">";
            $returnVal .= $value;
            $returnVal .= "</option>\n";
        }
        $returnVal .= "</select>";
        return $returnVal;
    }
    

    During the function we keep the selection statement we build in a string named $returnVal. At the end of the function we send the string back to the function call using a return statement:

    return $returnVal;

    For more information see section 9.1.6: Returning Values.

  12. When we return a value, we need to save the returned value in memory or pass it to another statement. For example, change the function call to:
    $selectList = makeSelect($name, $list);
    echo "$selectList\n";
    

    For more information see section 9.1.6: Returning Values.

  13. Make the changes to the function calls for both selection lists to save and display the return values. Reload (refresh) your browser page to make sure you still see the two selection lists.

    If you have problems, see the source code listing below.

  14. Submit your final funselect.php file to Blackboard as part of assignment 9.

Listing of funselect.php

Listing of funselect.php

As time permits, review the following parts of this section and be prepared to answer the Check Yourself questions in the section: 9.1.7: Summary.

9.1.4: Scope

  • To avoid name clashes between variables in different functions, PHP limits their scope
  • Variables declared inside a function only work within the function
  • When the function returns, the use of the variable is lost
    • The value of the variable is lost as well
  • Consider the following code:

<?php
$num1 
1;
$num2 5;
changeValues($num1$num2);
print 
"<br>\nNew values: ".$num1.", ".$num2."<br>\n";

function 
changeValues($num1$num2) {
    print 
"Original values: ".$num1.", ".$num2;
    
$num1++;
    
$num2++;
    print 
"<br>\nChanged values: ".$num1.", ".$num2;
}
?>

  • Running the code displays the output:

    Original values: 1, 5
    Changed values: 2, 6
    New values: 1, 5

  • Variables changed inside the function have no effect on variables outside the function

Using Global Variables

  • Variables declared outside of functions are called global variables
  • Global variables are not automatically available inside of functions
  • To use global variables within a function, use the keyword global followed by the variable name
  • As an example, we added a global statement inside the following function:

<?php
$num1 
1;
$num2 5;
changeValues2();
print 
"<br>\nNew values: ".$num1.", ".$num2."<br>\n";

function 
changeValues2() {
    global 
$num1$num2;
    print 
"Original values: ".$num1.", ".$num2;
    
$num1++;
    
$num2++;
    print 
"<br>\nChanged values: ".$num1.", ".$num2;
}
?>

  • Now changes made to the global variables inside the function are retained outside the function

9.1.5: Arguments and Parameters

  • One of the main reason to use functions is to let us reuse code without having to rewrite it
  • To make functions more flexible and thus reusable, we use arguments and parameters
  • Depending on your programming background, you might use the term arguments or parameters for the values passed into functions
  • The terminology is not that important
  • However, the way I will use the terms is:
    • A called function has parameters
      function printBold($text) {
          print "$text";
      }
      
    • A caller passes arguments
      printBold("This line is bold");
  • Arguments are values you pass into functions
  • When the argument drops into a function, it lands in a parameter
  • The parameter is just like a local variable in the function
    • Except that a parameter gets initialized by an argument
  • The important part is:

    If a function takes a parameter, you must pass it a value.

Example Function with Parameters

  • As an example, we can define a function to display text in boldface
  • Then we can call the function and see what happens
  • Here is the function definition followed by the function calls:

    <?php
    function printBold($text) {
        print 
    "<b>$text</b>";
    }

    print 
    "This line is not bold<br>\n";
    printBold("This line is bold");
    print 
    "<br>\nThis line is not bold";
    ?>

  • Running the code displays the output:

    This line is not bold
    This line is bold
    This line is not bold

How the Function Works

  • PHP ignores the function definition until it sees a function call
  • When a function is called, PHP jumps to the function definition
  • The argument "This line is bold" is copied to the parameter $text
  • Within the function the parameter is used like a variable
  • After the function is finished, PHP jumps back to the statement that called the function
  • Note that the parameter is no longer useable after the function is finished
  • Also, remember that function names are case-insensitive

Default Arguments

  • PHP allows functions with default arguments
  • If the argument is omitted during the function call, the function uses the default value instead
  • A default value is specified in a function's parameter list
  • Only the rightmost parameters can have default values
  • For example:
function calcVolume($length, $width = 1, $height = 1)
  • The last two parameters have default values
  • If we call a function without supplying the rightmost arguments, the default values are used instead
  • For instance, here are some possible function calls:
calcVolume(2, 4, 6); // all arguments supplied
calcVolume(3, 5);    // height defaulted to 1
calcVolume(7);       // width and height defaulted to 1

9.1.6: Returning a Value

  • To return a value from a function, you use a return statement
  • For example, the following uses the statement: return $text;

    <?php
    function makeBold($text) {
        
    $text "<b>$text</b>";
        return 
    $text;
    }

    print 
    "This line is not bold<br>\n";
    $line makeBold("This line is bold");
    print 
    $line."<br>\n";
    print 
    makeBold("This line is bold too!");
    print 
    "<br>\nThis line is not bold" ;
    ?>

  • Which displays the output:

    This line is not bold
    This line is bold
    This line is bold too!
    This line is not bold

  • When you return a value, you must save it in order to use it:
    $line = makeBold("This line is bold");
    print $line."<br>\n";
    
  • If you just want to save the value and just print it, then you can write something like:
    print makeBold("This line is bold too!");
    

Exiting Early

  • Sometimes you do not want to execute all the code in a function
  • You can use a return statement to stop execution and return from anywhere
  • Control returns immediately from a function when a return is executed
  • For example:

    <?php
    print "max(1, 2) = ".max2nums(1,2)."<br>\n";
    print 
    "max(2, 3) = ".max2nums(2,3)."<br>\n";

    function 
    max2nums($num1$num2) {
        if (
    $num1 $num2) {
            return 
    $num1;
        } else {
            return 
    $num2;
        }
    }
    ?>

  • Displays the output:

    max(1, 2) = 2
    max(2, 3) = 3

9.1.7: Summary

  • A function is a block of code that can be called using the function name
  • The syntax for calling a function is:
    functionName(parameterValues);
    
  • PHP has many functions you can use
  • When you write PHP pages, you often write your own function
  • The syntax for defining a function is:
    function functionName(parameters) {
        PHP commands
    }
    
  • Where the functionName is a name that the programmer chooses and parameters are values accepted by the function
  • To return a value from a functions, you use a return statement:
    return $value;
  • Variables declared inside a function can only be used within the function
  • When the function returns, the value of the variable is lost
  • Global variables are not automatically available inside of functions
  • To use global variables within a function, use the keyword global followed by the variable name
  • PHP does not support function overloading, but it does support default values

Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. What is the purpose of a function? (9.1.1)
  2. What is the syntax for calling a function? (9.1.1)
  3. If a PHP function already exists that does what you want, should you still write your own? (9.1.2)
  4. What is meant by the term, defining a function? (9.1.3)
  5. What is the syntax for defining a function? (9.1.3)
  6. What are the two variable scopes in PHP? (9.1.4)
  7. What scope does a variable have when it is declared inside a function? (9.1.4)
  8. How is information passed to a function? (9.1.5)
  9. How does a parameter differ from a variable? (9.1.5)
  10. What keyword do you use to return a value from a function? (9.1.6)
  11. When a value is returned from a function, what should you do with the value? (9.1.6)

9.2: Managing the Date and Time

Learner Outcomes

At the end of the lesson the student will be able to:

  • Get the date and time from PHP
  • Work with UNIX timestamps
  • Convert between PHP and MySQL date formats

9.2.1: Using the date() Function

  • The date function formats the date and time
  • It returns a string and has two parameters, one of which is optional
    string date(string format [, int timestamp])
  • The format string consists of one or more letters with special meaning
  • Letters of the format string are replaced with parts of the date and time
  • If no timestamp argument is provided, the current date and time is used
  • For example:

    <?php
    print date("m/d/y")."<br>\n";
    print 
    date("l F jS, Y @h:i A");
    ?>

  • Displays the output:

    02/08/12
    Wednesday February 8th, 2012 @01:35 AM

  • Characters not understood as format codes, like slash (/), are just printed
  • For a list of the format string letters see the PHP manual for: date

More Information

  • date: format a local date and time

9.2.2: Working with Timestamps

  • The second parameter to the date function was a Unix timestamp
  • Most Unix systems store the current date and time as a 32-bit integer
  • A timestamp contains the number of seconds since 1/1/1970
  • A timestamp provides a compact way to store a date and time value
  • Using a timestamp could create a January 19, 2038 problem
  • However, timestamps do not have a fixed size
  • Most computer systems will have a larger int size by 2038

Making Timestamps

  • To convert a date and time to a timestamp, you use mktime()
  • The syntax is:

    int mktime([int hour [, int minute [, int second [, int month [, int day [, int year [, int is_dst]]]]]]])

  • As the square brackets show, all the parameters are optional
  • For all those left out, the function uses the current time and date as a default value
  • For example:

    <?php
    $format 
    "l F jS, Y @h:i A";
    print 
    mktime()."<br>\n";
    print 
    date($formatmktime())."<br>\n";
    $ts mktime(date("H") + 50);
    print 
    "Fifty hours from now: $ts<br>\n";
    print 
    date($format$ts)."<br>\n";
    ?>

  • Displays the output:

    1328693718
    Wednesday February 8th, 2012 @01:35 AM
    Fifty hours from now: 1328873718
    Friday February 10th, 2012 @03:35 AM

  • Note the order of the parameters: why did the function designer choose that order?

9.2.3: Using the getdate Function

  • Another useful function is getdate():
    array getdate([int timestamp])
  • Returns an associative array with information about the timestamp
  • If no timestamp argument is provided, the current date and time is used
  • For example:

    <?php
    $dateArray 
    getdate();
    print_r($dateArray);
    ?>

  • Displays the source code:
    Array
    (
        [seconds] => 18
        [minutes] => 35
        [hours] => 1
        [mday] => 8
        [wday] => 3
        [mon] => 2
        [year] => 2012
        [yday] => 38
        [weekday] => Wednesday
        [month] => February
        [0] => 1328693718
    )
    
  • Note that key [0] is the timestamp

9.2.4: Converting Between PHP and MySQL Date Formats

  • MySQL works with dates in a YYYY-MM-DD format
  • You will usually want to perform some date conversion
  • You can convert the dates using either MySQL or PHP
  • We discussed using MySQL in lesson 5.4.5: Formatting the Date and Time
  • For example, you can use the DATE_FORMAT function with a query:
    SELECT DATE_FORMAT(dateColumn, '%m %d %Y')
    FROM tableName;
    
  • You can also retrieve a date and time column as a Unix timestamp
    SELECT UNIX_TIMESTAMP(dateColumn)
    FROM tableName;
    
  • You can convert date and time formats using PHP as well
  • Two useful functions for this are strtotime() to strftime()
  • You can use strtotime() to convert a date-time string into a timestamp
  • The typical usage syntax is:
    $timestamp = strtotime(timeString)
  • Where:
    • timestamp: a variable to store the returned value
    • timeString: the date-time string to convert
  • Once you have a timestamp, use strftime() to change the format using:
    $dateString = strftime(formatString [, timestamp])
    
  • Where:
    • dateString: a variable to store the formatted date
    • formatString: the formatting instructions
    • timestamp: the Unix timestamp number
  • For example:

    <?php
    $date 
    "2004-11-13";
    $ts strtotime($date);
    if (
    $ts !== -1) {
        
    $formattedDate strftime("%m/%d/%y"$ts);
    }

    print 
    "The original date is: $date<br>\n";
    print 
    "The formatted date is: $formattedDate";
    ?>

  • Displays the output:

    The original date is: 2004-11-13
    The formatted date is: 11/13/04

  • Note that strtotime() returns a -1 if it cannot convert the date-time string
  • Thus you can test for an error by comparing to: -1

Some Useful PHP Date and Time Conversion Functions

Function Description
strtotime() For converting a date-time string into a timestamp.
strftime() For formatting a timestamp in a locale specific manner.

9.2.5: Date Calculations

  • Timestamps are the easiest ways to work with dates and times in PHP
  • For instance, to find the difference between two times, just subtract them:
    $diff = $timestamp2 - $timestamp1;
  • If you want the difference in minutes, you divide by 60:
    print "Elapsed minutes: ".$diff / 60;
  • Use a similar technique for hours or days:
    $diffHours = floor($diff / 3600);
    $diffDays = floor($diffHours / 24);
    
  • You can add dates using the same techniques:
    $fiveDays = 5 * 24 * 60 * 60;
    $timestamp = $timestamp + $fiveDays;
    
  • You can code your own date and time functions using these techniques
  • We will explore using dates and times in the next exercise

Exercise 9.2

In this exercise we write a function that computes a date.

Specifications

  1. Copy the following PHP script into a text editor, save the file in your phptest directory as tomorrow.php, and then view the file as a Web page in your browser.
    <html>
    <head><title>PHP Script</title></head>
    <body>
    <?php
        // Enter your PHP code here
    
    ?>
    </body>
    </html>
    

    The page should be blank to start with.

  2. In your starter code, write a function named tomorrow() that accepts no parameters and that prints tomorrows date.
  3. Add a function call to your script that calls the tomorrow() function.
  4. Submit your final tomorrow.php file to Blackboard as part of assignment 9.

As time permits, be prepared to answer the Check Yourself questions in the section: 9.2.6: Summary.

9.2.6: Summary

  • Use the date function to get the date and time from your server
    print date("l F jS, Y @h:i A");
  • Another way to get the date and time is with the getdate function
    • Returns date and time information as an associative array
  • The easiest way to work with dates and times in PHP is to use timestamps
  • Timestamps are a count of the seconds since the start of January 1, 1970
  • To convert a date and time to a timestamp, you can use mktime
  • With timestamps, you can use arithmetic to calculate days:
    $fiveDays = 5 * 24 * 60 * 60;
    $timestamp = $timestamp + $fiveDays;
    
  • To convert date formats between PHP and MySQL, you can use either MySQL or PHP
  • In PHP, you can use strtotime() to convert a MySQL date into a timestamp
  • Once you have a timestamp, use strftime() to change the format

Quick Quiz

  1. The date() function will format the date and time.


  2. When performing arithmetic with a date or time, the easiest technique is to use a .
  3. Using the following code and assuming that $timestamp1 and $timestamp2 are valid timestamps, you can convert $diff to minutes using which of the following techniques?
    $diff = $timestamp2 - $timestamp1;


Check Yourself

As time permits, be prepared to answer these questions. You can find more information by following the links after the question.

  1. What is the purpose of the date() function (9.2.1)
  2. What unit of time is returned by the mktime() function? (9.2.2)
  3. What does the getdate() function return? (9.2.3)
  4. What SQL statement will return a date and time column as a timestamp? (9.2.4)
  5. What PHP function will convert a date and time value from MySQL into a timestamp? (9.2.4)
  6. What is the easiest way to find the difference between two dates? (9.2.5)

9.3: Organizing Form Pages

Learner Outcomes

At the end of the lesson the student will be able to:

  • Discuss how to organize web pages using functions
  • Verify user input from forms
  • Conditionally redirect a browser to another URI
  • Develop single page forms

9.3.1: Single Page Forms

  • So far we display our forms on one page and process them on another
  • However, this two page sequence makes error handling difficult
  • When we detect an error, we need to redisplay the form so the user can correct their errors
  • However, redisplaying the form is difficult when we have moved to a different page
  • The solution is to check the form on the same page on which it is displayed
  • Validating the data on the same page as a form is displayed is known as a single page form

Submitting the Form Data

  • To create a single page form, we must have the form submit its data to the same page on which form is displayed
  • We do this by setting the action attribute of the form to the current page
  • It is cumbersome to hard code the action attribute for every form page
  • A more versatile solution is to use $_SERVER['PHP_SELF'] as the form action
  • $_SERVER is an array containing information created by the web server
  • One of the array entries is PHP_SELF, whose value is the pathname of the currently executing page
  • For example, the following code displays: /cis165/09s/lesson09.php
    <?php echo $_SERVER['PHP_SELF'] ?>
    
  • As you can see $_SERVER['PHP_SELF'] makes a valid action attribute of a form
  • Thus, we can write a form element with an action attribute like:

    <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">

Testing for Form Submission

  • Once we direct form data to the same page, we need some way to test for form submission
  • To test for form submission, we just test for the presence of a form element
  • One way is to test for a named submit button
  • First we must add a name to a form button like:
    <input type="submit" name="submitTest" value="Submit">
    
  • Then we can test for the form button in PHP using code like:
    if (isset($_REQUEST["submitTest"])) {
        // process form data
    }
    
  • Another option is to add a hidden field to a form like:
    <input type="hidden" name="submitTest" value="1">
    
  • Then we test for the hidden field just like we test for the form button
  • Notice the use of isset() to prevent warning messages
  • Before the form is submitted, when it is first displayed, the submitTest form element is not present

Example of Single Page Form

<html>
<head><title>Single Page Form</title></head>
<body>
<h1>Single Page Form</h1>
<?php
if (isset($_REQUEST["submitTest"])) {
    echo 
"<p>The form was submitted</p>\n";
}
?>
<form action="<?php echo $_SERVER['PHP_SELF'?>"
   method="GET">
<input type="submit" name="submitTest" value="Submit">
</form>
</body>
</html>

More Information

9.3.2: Validating User Input

  • Part of processing the form data is verifying user input
  • To verify user input we write conditional statements like:
    $fullName = trim($_REQUEST["fullName"]);
    if ($firstName == "") {
        echo "You must enter your name";
    }
    
  • Checking for numbers is a little more difficult because all HTML form values are strings
  • For example, if we want to verify a user enters an integer number we might try to use the following:
    $age = trim($_REQUEST["age"]);
    if ($age < 0) {  // does not work for 39abc
        echo "Please enter a valid age.";
    }
    
  • PHP converts the string $age to a number in the relational expression: $age < 0
  • However, we run into trouble when someone enters a value like: 39abc
  • PHP will convert the 39 to a number and ignore the rest
  • To correct this problem we can use the type checking and type conversion functions listed below
  • For instance, we can rewrite our test condition like this:
    $age = trim($_REQUEST["age"]);
    if ($age != strval(intval($age)) or $age < 0) {
        echo "Please enter a valid age.";
    }
    
  • Here we convert $age to an integer and then back to a string
  • If $age has extra letters, they are removed during the conversions
  • Then we compare the original $age against the converted value to verify they are the same

Commonly Used Type Checking Functions

Function Description
is_array() For testing if a variable is an array.
is_bool() For testing if a variable is an boolean.
is_float() For testing if a variable is an float.
is_int() For testing if a variable is an integer.
is_null() For testing if a variable is set to NULL.
is_numeric() For testing if a variable is a number or a numeric string.
is_string() For testing if a variable is a string.

Commonly Used Type Conversion Functions

Function Description
floatval() For getting the floating point value of a variable.
intval() For getting the integer value of a variable.
strval() For getting the string value of a variable.

More Information

9.3.3: Redirecting the Browser

  • Sometimes you want to redirect a browser to another page
  • For example, after processing form data we may want to move the user to another page
  • One way to redirect pages is with the HTML refresh meta tag:
    <meta http-equiv="refresh" content="5;URL=http://bye.com">
    
  • However, this would not work well as a way to move on after processing form data
  • A faster and more flexible method is to use the PHP header() function
  • The header() function sends a "raw" HTTP header to the browser
  • To use the header() function for redirection, you code something like:
    header("Location: http://www.edparrish.com/");
    
  • Note that HTTP/1.1 requires an absolute URI as an argument to Location:
  • Thus, if you want to redirect to a page named login.html in the same directory, you should use something like:
    http://localhost/cis165/login.html
  • However, absolute URLs are not portable
  • When you move your code from one computer to another, the hostname and path can change
  • To resolve this problem, we can ask the server for its name:
    $host = $_SERVER['HTTP_HOST'];
  • Similarly, to get the pathname, we can use:
    $path = dirname($_SERVER['PHP_SELF']);
  • Thus, to redirect the browser to a page named login.html located in the current directory:
    $host = $_SERVER['HTTP_HOST'];
    $path = dirname($_SERVER['PHP_SELF']);
    $file = "login.html";
    header("Location: http://$host$path/$file");
    
  • You can write a function to handle the details like the following:

<?php
function redirect($url) {
    
$url trim($url);
    
$absURL "Location: ";
    if (
substr($url01) == "/") {
        
$absURL .= "http://".$_SERVER['HTTP_HOST'];
    } elseif (
strtolower(substr($url07)) != "http://") {
        
$absURL .= "http://".$_SERVER['HTTP_HOST'];
        
$absURL .= dirname($_SERVER['PHP_SELF'])."/";
    }
    
$absURL .= $url;
    
header($absURL);
    
// Make sure nothing else happens
    
die("Could not redirect");
}
?>

  • Using this function, you can redirect the browser in a number of ways:
    redirect("http://www.edparrish.com");
    redirect("/index.html");
    redirect("../index.php");
    redirect("login.html");
    
  • We can place the redirect() function in an included file
  • However, when doing so means we should use a function named ob_start() as explained below

Important Note

  • The header() function must be called before any output is sent to the browser
  • This includes:
    • HTML tags
    • Blank lines or even a single blank space
    • Any other content
  • It is easy to overlook a single blank line or space in your PHP files
  • You can avoid problems by using a function named ob_start()
  • The function ob_start() turns on output buffering
  • When output buffering is turned on, no output is sent other than header files
  • Thus you want put the call to ob_start() as your very first line of code on a page where you are using a redirect:
    <?php ob_start() ?>
  • However, you still must avoid putting any blank lines or even spaces before calling ob_start()
  • Also, you must place ob_start() before any included file to prevent problems
  • A common programming error is to have included files before calling header() that unintentionally add spaces or blank lines to a page
  • Do NOT commit this damaging error!

9.3.4: Organizing Pages with Functions

  • As we have seen, there are many details for handling forms
  • To make form handling easier, we can follow a template or design pattern
  • To develop our template, we observe that form handling follows these steps:
    • Show the form page
    • Verify the form data
    • Process the form data
  • We can organize and simplify our form processing by using functions for each step
  • In addition we can use a function to control the form handling sequence
  • The following template is a layout we can use for pages that handle forms
  • Notice there are four function in the template:
    • main(): control the form handling steps
    • checkForm(): verify the form data
    • processData(): do something with the data
    • showContent($errors): display the form page
  • Also note how the entire page has one entry point: main()
  • Thus the page does not have any error prone global code

Page Template

<?php
ob_start();
require_once "includes/redirect.php";

// Page starts and stops with this function call
main("A Well-Organized Page");

// Form processing logic
function main($title = "") {
    $errors = "";
    if (isset($_POST["submitTest"])) {
        $errors = checkForm();
        if (!$errors) { // data is OK
            processData();
            redirect("echo.php?it=worked");
        }
    }
    include "includes/header.php";
    showContent($title, $errors);
    include "includes/footer.php";
}

// Check the input form for errors
function checkForm() {
    $error = "";
    // Add code to test form values and record errors
    return $error;
}

// Process the data
function processData() {
    // Process the verified data here.
    // This is where you save data in the database.
}

// Display the content of the page
function showContent($title, $errors) {
    echo "<h1>$title</h1>\n";
    if ($errors) {
        echo "$errors\n";
    }
// Put HTML after the closing PHP tag
?>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>"
  method="post">
<!-- Other form elements here -->
<input type="submit" name="submitTest" value="Submit">
</form>

<?php
}
?>

Redirections and Query Strings

  • In main(), the page redirects after verifying and processing the form data:
    redirect("echo.php?it=worked");
  • The redirect() function specifies a page name: echo.php
  • Using echo.php (from exercise 9.1) is useful during development
  • However, you will need to change the redirect location when finished
  • Notice that you can optionally pass information to the target page using a query string like: ?it=worked
  • A query string, also called CGI variables or request variables, is added to the end of a URL
  • The syntax for query strings:
    url?name1=value1&name2=value2&...
    
  • Where:
    • url: the URL of the web page or resource
    • nameX: the name of the data for use with $_REQUEST or $_GET
    • valueX: the value for the request variable
  • Thus in the above example the name of the request variable is "it" and the value is "worked"
  • We will discuss query strings in more detail later in the course

9.3.5: Processing Data

  • After verification, we need to process the form data in the processData() function
  • Oftentimes processing the data involves the use of a database
  • However, developing the correct sequence of statements for entering form data into a database can be error prone
  • To minimize the errors, it is important to consider your SQL statements one at a time
  • Also, you should write verify your SQL statements before you start accessing the database
  • The following is the recommended process for developing statements that access the database using form data

Recommended Process for Developing SQL Statements for Form Data

  1. First, identify the form data you need for your SQL statements like:
    $fullName = trim($_REQUEST["fullName"]);
    $age = trim($_REQUEST["age"]);
    
  2. Then write you SQL statement like:
    $sql = "
      INSERT INTO someTable(FullName, Age)
      VALUES ('$fullName', '$age')
      ";
    
  3. Following the SQL statement, add the following debugging statements:
    // For debugging (remove when finished)
    print_r($_REQUEST);
    echo "<p>SQL: $sql</p>\n";
    die("Stopped for testing"); // stop the redirect
    
  4. Run your form page in a Web browser, enter valid data and press the submit button.

    You should see a page with your form data, a SQL statement and the message:

    Stopped for testing
  5. Verify the SQL statement is correct for the form data you entered.

    For instance, try copying the SQL statement into phpMyAdmin to see if it enters the data.

  6. Once you are certain that the SQL is correct, remove the debugging statements and then verify your form data was entered into your database correctly.

    Examine your database using phpMyAdmin and verify the data you entered appears in the correct table.

Example processData() Function with Debug Statements

// Process the data
function processData() {
    require "includes/dbconvars.php";
    $dbCnx = mysql_connect($dbhost, $dbuser, $dbpwd)
        or die("Could not connect: ".mysql_error());
    mysql_select_db($dbname, $dbCnx)
        or die("Could not select db: ".mysql_error());
    }

    $fullName = trim($_REQUEST["fullName"]);
    $age = trim($_REQUEST["age"]);

    $sql = "
      INSERT INTO someTable(FullName, Age)
      VALUES ('$fullName', '$age')
      ";

    // For debugging (remove when finished)
    print_r($_REQUEST);
    echo "<p>SQL: $sql</p>\n";
    die("Stopped for testing"); // stop the redirect

    mysql_query($sql)
        or die("Query failed: ".mysql_error());

    mysql_close($dbCnx);
}

9.3.6: Displaying Page Content

  • When displaying page content, it is helpful to print HTML form controls using functions
  • For example, we wrote a makeSelect() function in exercise 9.1
  • By keeping a library of functions we can make our form development easier
  • We leave the boring and repetitive work of constructing elements to the computer
  • We simply include the library when we want to use our functions and then call the functions
  • Next week we will explore how to do this in more detail

Using Heredoc

  • Note that you can put chunks of HTML within the PHP code
  • You just close the PHP tag, write the HTML, and open new PHP tags:
    <?php
    // PHP code
    ?>
    Write the HTML code here
    <?php
    // PHP code
    ?>
    
  • Another technique is to use the heredoc syntax:
    <?php
    // PHP code
    echo<<<identifier
    HTML code
    identifier;
    // PHP code
    ?>
    
  • Heredoc is just another way to delimit strings
  • Like double-quoted strings, the values of PHP variables are displayed
  • The added advantage of heredoc is that you can use double quotes inside the heredoc area
  • Note that the closing identifier must be flush left on a line by itself

Example Using Heredoc

<?php
$login 
"";
if (isset(
$_REQUEST["login"])) {
    
$login $_REQUEST["login"];
}
echo<<<HTML
<html>
<head> <title>Login Form</title> </head>
<body>
<h1>Please Login</h1>
<form action="heredoc.php" method="post" >
<p>Username:
<input type="text" size="15" name="login" value="$login">
<br>Password:
<input type="password" size="15" name="pwd">
</p>
<br> <input type="submit" value="Click To Login">
<input type="reset" value="Erase and Restart">
</form>
</body>
</html>
HTML;
?>

Retaining Data on Error

  • Notice the code at the top of the page:
    $login = "";
    if (isset($_REQUEST["login"])) {
        $login = $_REQUEST["login"];
    }
    
  • If the page was entered for the first time, then the value of $login is an empty string
  • However, if the form was previously filled out, then $login is assigned the value from the previous page entry:
    $login = $_REQUEST["login"]
  • We can display the contents of this variable later in the page:
    <input type="text" ... value="$login">
    
  • If you were not using heredoc, then the code would be:
    <input type="text" ... value="<?php echo $login ?>">
    
  • Use this technique when the user makes an error and you do not want to force the user to enter other data again

Exercise 9.3

In this exercise we build a single page form that collects data from the user and enters the collected data into a database.

Specifications

  1. Verify your computer has the following connection information in a file named dbconvars.php in a subdirectory named includes of the phptest directory:
    <?php
    $dbhost = "localhost";
    $dbuser = "root";
    $dbpwd = "";
    $dbname = "artzy";
    ?>
    

    If needed, change the values assigned to $dbuser and $dbpwd to match your MySQL installation. In the classroom, $dbuser = root; and $dbpwd = password;. For more information see lesson 6.3.1: Connecting to a MySQL Database.

  2. Next we need to save an included file. Copy the following code to your text editor and save the file in your phptest/includes directory as redirect.php
    <?php
    function redirect($url) {
        $url = trim($url);
        $absURL = "Location: ";
        if (substr($url, 0, 1) == "/") {
            $absURL .= "http://".$_SERVER['HTTP_HOST'];
        } elseif (strtolower(substr($url, 0, 7)) != "http://") {
            $absURL .= "http://".$_SERVER['HTTP_HOST'];
            $absURL .= dirname($_SERVER['PHP_SELF'])."/";
        }
        $absURL .= $url;
        header($absURL);
        // Make sure nothing else happens
        die("Could not redirect");
    }
    ?>
    

    For more information on the redirect function see section 9.3.3: Redirecting the Browser.

  3. Copy the following page template into a text editor, save the file in your phptest directory as onepageform.php, and then view the file as a Web page in your browser.
    <?php
    ob_start();
    require_once "includes/redirect.php";
    
    // Page starts and stops with this function call
    main("A Well-Organized Page");
    
    // Form processing logic
    function main($title = "") {
        $errors = "";
        if (isset($_POST["submitTest"])) {
            $errors = checkForm();
            if (!$errors) { // data is OK
                processData();
                redirect("echo.php?it=worked");
            }
        }
        include "includes/header.php";
        showContent($title, $errors);
        include "includes/footer.php";
    }
    
    // Check the input form for errors
    function checkForm() {
        $error = "";
        // Add code to test form values and record errors
        return $error;
    }
    
    // Process the data
    function processData() {
        // Process the verified data here.
        // This is where you save data in the database.
    }
    
    // Display the content of the page
    function showContent($title, $errors) {
        echo "<h1>$title</h1>\n";
        if ($errors) {
            echo "$errors\n";
        }
    // Put HTML after the closing PHP tag
    ?>
    <form action="<?php echo $_SERVER['PHP_SELF'] ?>"
      method="post">
    <!-- Other form elements here -->
    <input type="submit" name="submitTest" value="Submit">
    </form>
    
    <?php
    }
    ?>
    

    You should see a page like the following in the browser:

    For more information on the template see section 9.3.4: Organizing Pages with Functions.

  4. Let us first add a form to the showContent() function at the bottom of the page. After the comment that says:
    // Put HTML after the closing PHP tag
    replace the HTML with the following code:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    
    <form action="<?php echo $_SERVER['PHP_SELF'] ?>"
      method="post">
    <fieldset>
    <legend>Enter your shipping information</legend>
    
    <table>
    <tr>
    <td class="labelcell">First Name</td>
    <td class="inputcell">
      <input type="text" name="fname" size="35">
    </td>
    </tr>
    <tr>
    <td class="labelcell">Last Name</td>
    <td class="inputcell">
      <input type="text" name="lname" size="35">
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">Street</td>
    <td class="inputcell">
      <textarea name="street" cols="30"></textarea>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">City</td>
    <td class="inputcell">
      <input type="text" name="city" size="35">
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">State</td>
    <td class="inputcell">
      <select name="state">
        <option value="CA">- Select One -</option>
        <option value="CA">California</option>
        <option value="OR">Oregon</option>
        <option value="WA">Washington</option>
      </select>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">ZIP</td>
    <td class="inputcell">
      <input type="text" name="zip" size="10">
    </td>
    </tr>
    </table>
    </fieldset>
    
    <p id="formbuttons">
    <input type="button" name="prevb" value="Previous"
      onclick="history.back()">
    <input type="submit" name="submitTest" value="Next">
    </p>
    </form>
    

    Notice that this is the same form we developed in exercise 7.2. Refresh the page and verify you see the input elements. Try entering some data and pressing the Next button. Notice that the values entered are not checked.

  5. Now we want to verify the data that was entered. Add the following code to the checkForm() function after the comment that says:
    // Add code to test form values and record errors
    and before the return statement:
    $fname = trim($_REQUEST["fname"]);
    if ($fname == "") {
        $error .= "Please enter your first name.<br>\n";
    }
    $lname = trim($_REQUEST["lname"]);
    if ($lname == "") {
        $error .= "Please enter your last name.<br>\n";
    }
    $zip = trim($_REQUEST["zip"]);
    if ($zip != strval(intval($zip)) or $zip < 0) {
        $error .= "Please enter a valid zip.<br>\n";
    }
    

    For more information see section 9.3.2: Validating User Input.

  6. Reload (refresh) your form page and try to enter incorrect values such as:
    First Name: (leave blank)
    Last Name: (leave blank)
    ZIP: 123abc
    
    When you enter incorrect values you should see and error message such as:

    Please enter your first name.
    Please enter your last name.
    Please enter a valid zip.

    Notice that the user does not leave the form page until entering valid data. The logic for the form handling is contained in the main() function. For more information see section 9.3.4: Organizing Pages with Functions.

  7. After verification, we need to process the data and oftentimes processing the data involves the use of a database. Add the following code to the processData() function after the comment that says:
    // This is where you save data in the database.
    and before the closing curly brace (}):
    require "includes/dbconvars.php";
    $dbCnx = mysql_connect($dbhost, $dbuser, $dbpwd)
        or die(mysql_error());
    mysql_select_db($dbname, $dbCnx)
        or die(mysql_error());
    
    // Process the first query
    $street = trim($_REQUEST["street"]);
    $city = trim($_REQUEST["city"]);
    $state = trim($_REQUEST["state"]);
    $zip = trim($_REQUEST["zip"]);
    
    $sql = "
        INSERT INTO addresses(Address, City, State, Zip)
        VALUES ('$street', '$city', '$state', '$zip')
        ";
    
    // For debugging (remove when finished)
    print_r($_REQUEST);
    echo "<p>SQL: $sql</p>\n";
    die("Stopped for testing"); // stop the redirect
    
    mysql_query($sql)
        or die("Query failed: ".mysql_error());
    $addressID = mysql_insert_id();
    
    // Process the second query
    $fname = trim($_REQUEST["fname"]);
    $lname = trim($_REQUEST["lname"]);
    
    $sql = "
      INSERT INTO customers(LName, FName, AddressID)
      VALUES ('$lname', '$fname', $addressID)
      ";
    
    // For debugging (remove when finished)
    print_r($_REQUEST);
    echo "<p>SQL: $sql</p>\n";
    die("Stopped for testing"); // stop the redirect
    
    mysql_query($sql)
        or die("Query failed: ".mysql_error());
    
    mysql_close($dbCnx);
    

    Notice that this is like the database entry script we developed in exercise 7.3.

  8. Reload (refresh) the your form page and enter valid data in the input fields. After you press the Next button you should see a page with your form data, a SQL statement and the message:
    Stopped for testing

    The information is the data you entered and the SQL statement to enter in the database. The page displayed information and stopped processing because of the following statements:

    // For debugging (remove when finished)
    var_dump($_REQUEST);
    echo "<p>SQL: $sql</p>\n";
    die("Stopped for testing"); // stop the redirect
    

    These statements are there to verify the SQL statement before you continue, since it is easy to make errors when developing SQL statements. For more information see section 9.3.5: Processing Data.

  9. Verify the SQL statement is correct for the form data you entered.

    For instance, try copying the SQL statement into phpMyAdmin to see if it enters the data.

  10. Once you are certain that the SQL statement is correct, remove the debugging statements and then verify your form data was entered into your database correctly.

    Examine your database using phpMyAdmin and verify the data you entered appears in the correct table.

  11. Reload (refresh) the your page and repeat the development process for the second SQL statement. Once you are certain that the SQL statement is correct, remove the debugging statements and then verify your form data was entered into your database correctly.

    Examine your database using phpMyAdmin and verify the data you entered appears in the correct table.

  12. Submit your final single-page-form file to Blackboard as part of assignment 9.

As time permits, be prepared to answer the Check Yourself questions in the section: 9.3.7: Summary.

9.3.7: Summary

  • In this section we looked out how to validate form data on the same page it is displayed
  • We start by having the form submit its data to the same page on which it is displayed
  • We do this by setting the action attribute of the form to the current page
  • A convenient and portable way to accomplish this is to use $_SERVER['PHP_SELF'] as the form action:

    <form action="<?php echo $_SERVER['PHP_SELF'] ?>" method="post">

  • Once we direct form data to the same page, we need some way to test for form submission
  • To test for form submission, we just test for the presence of a form element like a named submit button
  • First we must add a name to a form button like:
    <input type="submit" name="submitTest" value="Submit">
    
  • Then we can test for the form button in PHP using code like:
    if (isset($_REQUEST["submitTest"])) {
        // process form data
    }
    
  • Part of processing the form data is verifying user input
  • For this we use conditional statements like:
    $age = trim($_REQUEST["age"]);
    if ($age != strval(intval($age)) or $age < 0) {
        echo "Please enter a valid age.";
    }
    
  • Type checking and type conversion functions are useful when verifying user input
  • In addition, we looked at how to redirect a user using the header() function
  • Also, we looked at organizing pages with functions to make form pages easier to develop
  • As part of processing form data we looked at how to develop statements that access the database using form data

Quick Quiz

  1. To test if a single-page form has been submitted, check if a declared form variable exists using isset().


  2. To make a form send information to the current page, use action="" in the form tag.

  3. Which of the following is not one of the PHP type-checking functions?


Check Yourself

  1. True or false? The key to a single page form is to submit the form to the same page as the form is displayed. (9.3.1)
  2. To test for the submission of a form, what do you test for? (9.3.1)
  3. What code would you write to determine if a form field named "foo" has a value? (9.3.2)
  4. Which PHP function do you use to redirect a browser? (9.3.3)
  5. What three steps do you follow for almost every form? (9.3.4)
  6. Why is it a good practice to examine a SQL statement while developing a PHP that saves data in a database? (9.3.5)
  7. Why is using functions to display HTML elements a good practice? (9.3.6)

Wrap Up

Due Next:
A9-Single-Page Form (4/27/09)
Quiz 9 and Discussion Chapter 10 (4/27/09)
When class is over, please shut down your computer if it is on
Home | WebCT | Announcements | Course info | Expectations | Schedule
Project | Help | FAQ's | HowTo's | Links
Last Updated: April 17 2009 @16:02:38