10. OOP and Forms

What We Will Cover


Elucidations

Homework Questions?

Quiz Questions?

Questions from last class?

10.1: Object-Oriented PHP

Learner Outcomes

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

  • Write code that defines a class
  • Create objects from classes
  • Use objects in programs

10.1.1: About Object-Oriented Programming

  • Object-oriented programming (OOP) was developed to solve problems with large programming projects
  • Since it was so useful, OOP has become a part of most programming languages
  • More and more people are writing PHP programs using OOP
  • You need to learn OOP to understand and apply its benefits to your programs

Advantages of OOP

  • OOP lets you develop modules for building large projects
  • Properly implemented, the modules are self-contained
  • You can make changes within a module without affecting the rest of the project
  • A well-built module can make building smaller projects easier as well

Designing OOP Modules with Classes

  • You design an OOP module using a class
  • A class is like a software box that contains both variables and functions
  • The variables are the data on which the module is based
  • For instance, you decide to make a class for a user in your project
  • For the user class, you want to include information about a user like:
    • username: the login name for a user
    • password: a password for a user
    • validated: whether or not the user login and password is valid
  • After deciding on the data for the class, you develop functions
  • The functions are the operations that work with your data
  • For our example, we write functions that maintain information about the user, like:
    • A function to initialize the variables
    • A function to check a username and password
    • A function to get the username
  • The functions are how other parts of the project work with your module
  • Collectively, these functions are known as the interface of a class
  • Putting the variables and functions into a class is known as encapsulation
  • We will explore the syntax and mechanics of writing classes in the following sections

PHP Object Models

  • Different versions of PHP have different object models
  • PHP 5 presented a new object model with enhanced features
  • However, the PHP 4 object model still works with PHP 5
  • Many ISP's still run web servers with PHP 4
  • We will be using PHP 5 syntax in this lesson
  • To allow you to work with PHP 4, I will point out the differences along the way

10.1.2: Defining a Class

  • The syntax for coding a class is:
    class ClassName {
        private $memberVariable;
    
        function memberFunction($arg1, $arg2, ...) {
            // commands
        }
    }
    
  • Where:
    • ClassName: the name you make up for the class
    • memberVariable: variables encapsulated in the class
    • memberFunction: functions encapsulated in the class
  • The following is an example of a class
  • Note the new features in the code
  • We will examine these new features in more detail in the following sections

Example of a Class

<?php
// Define a class for tracking users
class User {
    
// Class variables
    
private $name$pwd$validated;

    
// Constructor
    
function __construct($name$pwd) {
        
$this->name $name;
        
$this->pwd $pwd;
        
$this->validated false;
    }

    
// Validate the user
    
function checkLogin($name$pwd) {
        
$this->validated false;
        if (
$this->name == $name
                
and $this->pwd == $pwd) {
            
$this->validated true;
        }
        return 
$this->validated;
    }

    
// Accessor function returns the variable
    
function getUserName() {
        return 
$this->name;
    }
}

// Construct an object
$ed = new User("eparrish""abc123");
// Call a member function of the object
echo 'The name of $ed is '.$ed->getUserName()."<br>\n";

// Check username and password
if ($ed->checkLogin("eparrish""abc123")) {
    echo 
$ed->getUserName()." is logged in<br>\n";
} else {
    echo 
"Invalid login<br>\n";
}

?>

Displays the output:

The name of $ed is eparrish
eparrish is logged in

Class Members and $this

  • Notice the use of $this in the above example
  • Member functions and variables work like other PHP functions and variables
  • However, to access them you must use -> operator
  • Within the class, you must use the $this variable to access a member variable or function
    $this->name;
    $this->getUserName();
    
  • Outside the class, you must create an object and use the object name with the -> operator
  • We will discuss creating objects later

Programming Style: Class Naming Conventions

  • Use nouns to name classes -- they represent objects
  • Start class names with a capital letter
  • Capital letter differentiates classes from methods (class member functions) and variables

10.1.3: Declaring Member Variables

  • Recall the member variables declared in the User class:
    // Class variables
    private $name, $pwd, $validated;
    
  • The keyword private "hides" the data by preventing access to the variables outside the class
  • If you try to access a variable like $name outside the class:
    echo $ed->name; // NO!
    
  • You get an error message like:

    Fatal error: Cannot access private property User::$name in user.php line 39

  • Without the keyword private, we could access the $name variable outside the class
  • However, good OOP practice says that data (variables) should be private
  • Making variables private is an important OOP concept known as information hiding

Information Hiding

Information hiding: hiding the parts of the design that are most likely to change (a.k.a. data hiding)

  • As programming projects develop, developers change them frequently
  • Even after a program is first completed and released, successful programs are updated with new features
  • With large programs, making a change in one area can cause problems in other areas
  • For instance, suppose we decide to change the way we use $name and $password
  • Instead of just storing them in member variables, we decide to store them in a database
  • If our project used the variables directly, we would have to change many of its parts
  • Making changes takes time, you may miss one or more changes and bugs creep into your project
  • Instead, we "hide" the variables by making them private
  • Then we allow access only through the functions, which are how other parts of the project use the class
  • When we make a change, we keep our function name and parameters the same, but change the PHP statements inside the function body
  • The ability to change parts of a program without affecting other parts becomes more important as programs grow larger

Member Variables in PHP 4

  • In PHP 4, member variables are declared using the keyword: var
    var $name, $pwd, $validated;
    
  • Unfortunately, PHP 4 does not support data hiding
  • The keyword var is a synonym for public access

More Information

10.1.4: Class Functions

  • To make use of our class, we must define class member functions, also known as methods
  • An interface defines how other parts of the project can make use of the class
  • The interface consists of all member functions we want to define for working with the class and its data
  • For instance, we defined two functions for the User class interface:
    // Validate the user
    function checkLogin($name, $pwd) {
        $this->validated = false;
        if ($this->name == $name
                and $this->pwd == $pwd) {
            $this->validated = true;
        }
        return $this->validated;
    }
    
    function getUserName() {
        return $this->name;
    }
    
  • These are actions that we needed to take for working with a user
  • If we wanted more actions, we would define more functions

10.1.5: Coding Constructors

  • The constructor is a special purpose function whose primary purpose is to initialize the object variables
  • Syntax for declaring constructors:
    function __construct($param1, $param2, ...) {
        // statements to initialize object variables
        // other initializing statements as needed
    }
    
  • Where paramX is the list of parameters, just like other functions
  • Notice that there are two underbar characters before the keyword construct
  • In the following example, the constructor initializes three member variables
  • Notice the use of the special $this variable
  • We will discuss $this shortly

Example of a Constructor

function __construct($name, $pwd) {
    $this->name = $name;
    $this->pwd = $pwd;
    $this->validated = false;
}

Constructors in PHP 4

  • Syntax for declaring constructors in PHP 4:
    function ClassName($arg1, $arg2, ...) {
        // statements to initialize object variables
        // other initializing statements as needed
    }
    
  • Where ClassName is the same name and capitalization as the class name
  • Note that you can use PHP 4 constructor syntax in PHP 5

Example Constructor in PHP 4

// Constructor
function User($name, $password) {
    $this->name = $name;
    $this->pwd = $pwd;
    $this->validated = false;
}

More Information

10.1.6: Creating an Object and Calling a Function

  • After designing the class, making use of one is simple:
    1. Construct an object
    2. Use the object to call member functions
  • Syntax for constructing an object from a class:
    $objectName = new ClassName($arg1, $arg2, ...);
    
  • Where:
    • objectName: the object (variable) name
    • ClassName: the name of the class
  • For example:
    $ed = new User("eparrish", "abc123");
    
  • When you construct an object, many things happen automatically:
    1. PHP sets aside memory space for all the member variables
    2. PHP calls the constructor function
  • In the constructor, your code initializes the member variables
  • Once you construct an object, you can call the member functions of the object:
    echo 'The name of $ed is '.$ed->getUserName()."<br>\n";
    

Tracing the Flow of Control

  • You can trace the program flow for constructing an object:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    
    class User {
        // Class variables
        private $name, $pwd, $validated;
    
        // Constructor
        function __construct($name, $pwd) {
            $this->name = $name;
            $this->pwd = $pwd;
            $this->validated = false;
        }
        // other functions left out
    }
    
    // Construct an object
    $ed = new User("eparrish", "abc123");
    // Call a member function (method)
    echo 'The name of $ed is '.$ed->getUserName()."<br>\n";
    
  • The action starts on line 15, because a class is ignored until you construct an object
  • When the program executes the new operator, PHP allocates memory space for the member variables
  • Every object has it own unique memory space for member variables
  • After allocating memory space, PHP calls the constructor function
  • During the function call, PHP copies the arguments to the function parameters:
    • $name gets "eparrish"
    • $pwd gets "abc123"
  • Within the constructor, the code assigns the parameters to the member variables:
    • $this->name gets the value of $name
    • $this->password gets the value of $password
  • The code also sets the other member variable to a default value:
    • $this->validated gets false
  • Now that it is done, the constructor function returns to line 15 and the object $ed has been constructed
  • To the part of the project using the object, all that happened in one line:
    $ed = new User("eparrish", "abc123");
    

The Difference Between Classes and Objects

  • What is the difference between a class and an object?
  • A class is the design or definition of a module
  • An object is one of the modules
  • By analogy, a class is like the design of a house (blueprints)
  • You need to construct the house from the design before you can use the object:

    House construction from blueprints

  • Other analogies may help understanding:
    • Cookie cutter and cookies: a class is like a cookie cutter and objects are like cookies
    • Mold and Pots: a class is like a mold and objects are the clay pots coming out of the mold.
    • Dog and Fido: a class is like the concept of a dog and objects are individual animals like Fido.
    • Stencil and drawings: a class is like stencil and objects are the drawings made from the stencil.
    • User and people: a class is like the concept of a user and the objects are the individual people using the system
  • In other words, a class is a software template used to construct software objects
  • In the next exercise we put these ideas into practice to create a class and then construct objects from the class template

Exercise 10.1

In this exercise we code a PHP class and construct multiple objects.

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:
    <?php
    $title = "PHP Script";
    include "includes/header.php";
    print "<h1>$title</h1>";
    
    // Enter PHP code here
    
    include "includes/footer.php";
    ?>
    

    Save this code in a file named product.php to the htdocs directory and phptest subdirectory (htdocs/phptest) of your Apache (XAMPP) installation.

  4. Let us write a class named Product starting with the following code:
    // A class representing products
    class Product {
        // Add class variables here
    
        // Add constructor here
    
        // Add other class functions here
    
    }
    

    For more information see section 10.1.2: Defining a Class.

  5. Declare two class variables named $name and $description, used to describe the product object. For instance, here is the $name variable:
    private $name;
    

    For more information see section 10.1.3: Declaring Member Variables.

  6. Now that we have declared class variables, we need to code a constructor to initialize the variables. Use the following code to add a constructor to the class:
    function __construct($name, $description) {
        $this->name = $name;
        $this->description = $description;
    }
    

    For more information see section 10.1.5: Coding Constructors. Also notice the use of $this in front of the class variables and function calls. For more information see section 10.1.2: Defining a Class.

  7. Now we want to add a class function to display a product as part of the class interface. Add the following function to the class:
    // Show data for this product
    function show() {
        echo "<p>$this->name: $this->description</p>";
    }
    

    For more information see section 10.1.4: Class Functions.

  8. Now that we have defined our class, new need to construct objects from the class. Objects are constructed outside the class definition using the new keyword. Add code to construct at least two objects using code like:
    $milk = new Product("Milk", "Delicious moo juice!");
    

    For more information see section 10.1.6: Creating an Object and Calling a Class Function.

  9. After constructing our objects, we can call the class member functions. Add code to call the show() function of each object using code like:
    $milk->show();
    
  10. Depending on the object you constructed, you should see output like:

    Milk: Delicious moo juice!

    Bread: Hearty whole-grain goodness!

  11. Submit your final product.php file to Blackboard as part of assignment 10.

One possible answer (Try it!)

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

10.1.7: Summary

  • OOP (object-oriented programming) lets you create modules that can be reused
  • All code is encapsulated in one place
    • Variables are stored in an object
    • Functions are included that work with those variables
  • Syntax for coding a class:
    class ClassName {
        private $classVariable;
    
        function classFunction($arg1, $arg2, ...) {
            // PHP commands
        }
    }
    
  • Where ClassName is the name you make up for the class
  • To instantiate (create) an object from a class, you use the new operator:
    $ed = new User("eparrish", "abc123");
    
  • Classes have a special function, called a constructor, to initialize object variables
  • Constructors are called when the class is created with the new operator
  • Object functions and variables are like other PHP functions and variables
  • However, to call them you must use -> operator
  • Within the class, you must use the $this variable to access an object variable or function:
    $this->name
  • Outside of the class, you use the $objectName to reference a variable or function
    $ed->getUserName()
    
  • You can create as many objects as you need for an application
  • Each object is separate in memory with its own storage space
  • In the next section we will look at how to use classes and objects to make writing forms easier

Check Yourself

  1. What are the main advantages of object-oriented PHP? (10.1.1)
  2. What keyword identifies the definition of a class? (10.1.2)
  3. Inside a class, what special variable is used to identify a class member? (10.1.2)
  4. What keyword identifies the declaration of a class variable? (10.1.3)
  5. What is meant by the term "information hiding"? (10.1.3)
  6. What is the interface of a class? (10.1.4)
  7. How does a member function differ from a nonmember function? (10.1.4)
  8. What is a constructor and what is its purpose? (10.1.5)
  9. How can you identify a constructor from all the other class functions? (10.1.5)
  10. Given a class named Foo, what code do you write to construct an object of the class? (10.1.6)
  11. For the object declared in the previous question, what code do you write to call a public member function named bar()? (10.1.6)

10.2: Form Verification

Learner Outcomes

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

  • Apply their knowledge of classes to a design problem
  • Use a class to verify form data

10.2.1: Design Specifications

  • A common programming activity for web developers is creating forms
  • There are many problems to overcome when designing a professional form
  • One of the problems is to verify the data a user enters
  • Failure to build in error checking can cause wrong results or worse
  • Checking input for errors is often necessary to ensure:
    • Required fields are not left blank
    • Numbers are within a certain range
    • Date values are valid
    • Email addresses are valid
    • Malicious data was not entered
  • Most, but not all entry errors come from text fields
  • You can prevent many data entry errors by designing an input form using non-textual elements
  • However, not all data can be collected easily without text fields
  • Error checking can, and should be, done on the client with JavaScript
    • Javascript is beyond the scope of this course
    • You can take CIS-132 to learn JavaScript
  • However, you still need to verify form data on the server
  • Otherwise, people can bypass your error checks by disabling JavaScript or by some other means

Form Verification Requirements

  • We want a reusable code library that operates as follows:
    1. The form is displayed and the user fills it in.
    2. The user submits the form to the server.
    3. If they left something out or provided invalid input, the form is redisplayed with the data that they already entered.
    4. The redisplayed form tells the user what is wrong and flags the incorrect fields.
    5. The application loops until the user fills the form in correctly.
  • Also, we want to tailor the error messages to the problem and control how incorrect fields are flagged
  • In addition, we would like all our form and validation code on one page

Form Example

10.2.2: Form Page Organization

  • Before we go into detail about our form verification library, let us discuss how we would use it
  • One of our design objectives is putting all the code for a form on one page
  • To accomplish this task, we set the form action to the current page:
    <form action="<?php echo $_SERVER['PHP_SELF'] ?>"
       method="post">
    
  • To help us process the form correctly, we organize our page using functions
  • This is very similar to the page organization we used in lesson 9.3.4
  • You can see the structure of a form page organized with functions in the following code listing
  • Notice the ampersand (&) in checkForm()
  • The ampersand (&) is important to preserve the error messages
  • Also note that changes in main() to work with the FormVerifier class

Example Page Structure

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
<?php
ob_start();

include "includes/redirect.php";
include "includes/formverifier.php";

// Page starts and stops with this function call
main("Classy Form");

function main($title = "") {
    $f = new FormVerifier();
    if (isset($_REQUEST["submitTest"])) {
        checkForm($f);
        if (!$f->isError()) { // data is OK
            processData($f);
            redirect("echo.php?it=worked");
        }
    }
    include("includes/header.php");
    showContent($title, $f);
    include("includes/footer.php");
}

// Check the input form for errors
function checkForm(&$f) {
    // Add code to test form values and record errors
}

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

function showContent($title, $f) {
?>
<h1><?php echo $title ?></h1>

<?php echo $f->reportErrors() ?>
<form action="<?php echo $_SERVER['PHP_SELF'] ?>"
  method="POST" >
<!-- Other form elements here -->
<input type="submit" name="submitTest" value="Submit">
</form>

<?php
}
?>

10.2.3: Architecture and Inheritance

  • Now lets discuss how we build our form verification library
  • We will use classes for our design to gain the benefits of OOP:
    • Encapsulated data for data hiding and easier data handling
    • Reusable code for other pages and applications
    • Easier updates for when you make changes
    • Removal of potential namespace clashes
  • In brief, we will have the following in our class:
    1. An array to hold a list of errors encountered during validation
    2. Other private data variables as needed
    3. General purpose functions such as constructors
    4. Functions to handle and report errors
    5. Functions to validate user-supplied data
    6. Functions for creating various form elements
  • Some people may not want to use a class for creating form elements
  • To accommodate them, we split our design into two parts:
    1. FormVerifier: first 5 items
    2. FormLib: full-featured form library
  • The two parts of our design are connected using inheritance

Inheritance

Inheritance: the ability to derive new classes from existing ones.
  • Inheritance is another feature of object-oriented programming
  • It lets you inherit all the variables and functions of another class
  • A class that inherits is called the subclass (derived, child)
  • A class that is inherited from is called the superclass (base, parent)
  • In a subclass, you can define new fields and methods not found in the superclass
  • To implement inheritance in PHP, you use the extends keyword
  • So to connect our two classes using inheritance, we use the code:
    class FormLib extends FormVerifier
    
  • All the variables and functions of FormVerifier are included in FormLib
  • We will add more class variables and functions to FormLib

10.2.4: Class Design Overview

  • The following is the structure of our FormVerifier class
  • We have two "private" variables
  • $errorList: stores a list of errors as they are encountered
  • $cssClass: stores the CSS class name we will use for error messages
  • Our constructor sets the value of $cssClass
  • We would call our constructor using something like:
    $f = new FormVerifier();
  • In addition, we will add several functions for error handling and verification

FormVerifier Class Structure

class FormVerifier {
    //---- private variables ----
    private $errorList = array();
    private $cssClass;

    //---- General purpose functions ----
    // constructor
    function __construct($cssClass = "error") {
        $this->cssClass = $cssClass;
    }

    //---- Error tracking and reporting functions ----

    //---- User input verification ----
}

Getting a Form Value

  • One of the basic operations we need is to get a value from the form into our PHP code
  • For this we can use the $_REQUEST[] superglobal array
    $_REQUEST["submitTest"]
  • However, we do not always know if a form value has been set
  • When form variables are not set, we get warning messages, or even worse, logic errors:
    Notice: Undefined variable: dbpw in dbentry.php on line 40
    
  • To avoid this problem, we test all form variables before using them
  • The algorithm is: given the name of a form element:
    • If the field is set, then we return its value
    • Otherwise, we return a default value
  • We code this algorithm into a function named getValue()

Code for getValue() Function

<?php
// function to get the value of a form field
function getValue($field$defaultVal "") {
    if (isset(
$_REQUEST[$field])) {
        return 
$_REQUEST[$field];
    }
    return 
$defaultVal;
}
?>

  • The function accepts an optional default value in case we want to preset a value in the field
  • We add this function to the FormVerifier class
  • To call the function, we use code like:
    $name = $f->getValue("name");
  • Note that you can use other superglobal arrays as shown below

Superglobal Arrays used with Forms

Array Description
$_GET Access to variables passed via the HTTP GET method.
$_POST Access to variables passed via the HTTP POST method.
$_REQUEST Access to variables passed via both the HTTP GET and POST methods.

10.2.5: Verifying Form Data

  • To check for errors, we code and use various error-checking functions like:
    isEmpty($field, $errorMsg)
  • To use the functions, we need to know which field to check
  • We also need to provide an error message if the value fails to validate
  • To accomplish this, we will pass two arguments to each verification function:
    1. Name of the field to validate
    2. Error message if the validation fails
  • Anytime a value fails to validate, the function adds the message to an error list

Possible Functions

  • To verify that a form element is not empty:
    isEmpty($field, $errorMsg)
  • To verify that the form variable contains numeric data:
    isNotNumeric($field, $errorMsg)
  • To verify that the form variable contains an integer value:
    isNotInteger($field, $errorMsg)
  • To verify that numeric data falls within a specified range:
    isOutsideRange($field, $errorMsg, $min, $max)
  • With these functions in mind, coding becomes straightforward
  • You can see the complete code by following the link:
  • Later in the course we will look at using regular expressions to verify data

Using the Verification Functions In A Form Page

  • To use the functions, we add them to the checkForm() function of our page structure
  • For example:
function checkForm(&$f) {
    // Code verification tests here
    $f->isEmpty('name', "You must enter a name");
    $f->isEmpty('state', "You must select a state");
    $f->isEmpty('lang', "You must select a language");
}
  • Notice the ampersand (&) in the checkForm() function definition
  • The ampersand means the function parameter is call-by-reference rather than the default call-by-value
  • Call by reference lets changes to the FormVerifier object remain after returning from the function
  • For more information see: Making arguments be passed by reference

10.2.6: Error Tracking and Reporting

  • We need to add a few more functions to our FormVerifier interface
  • Whenever we find an error, we want to add the error to a list
  • For each error, we will track its form-field name, value and a message:
    function addError($field, $value, $msg) {
        $this->errorList[$field] = array(
            "field" => $field,
            "value" => $value,
            "msg" => $msg);
    }
  • Also, we need a function to test if there are any errors:
    function isError() {
        if ($this->errorList) {
            return true;
        } else {
            return false;
        }
    }
    
  • We may need to reset the error list from time to time:
    function resetErrorList() {
        $this->errorList = array();
    }
  • As a convenience, we can code a function to display all the errors:
    function reportErrors() {
        $html = "";
        if ($this->isError()) {
            $html = "<strong>We found some error(s) in the data.</strong>\n";
            $html .= "<p>Please resubmit after making these changes:</p>\n";
            $html .= "<ul>";
            foreach ($this->errorList as $err) {
                $html .= '<li>'.$err['msg']."</li>\n";
            }
            $html .= "</ul>";
        }
        return $html;
    }
    
  • To show this error report, we call the function in our form using code like:
    <?php echo $f->reportErrors() ?>
    
  • Also, we want some way of highlighting errors on the form
    • Makes it easier for users to correct the errors
  • One way is to add some special highlighting HTML when an error occurs
  • We can create a function to add this HTML when a form variable is on the error list:
    function formatOnError($field, $formElement) {
        $html = $formElement;
        if (isset($this->errorList[$field])) {
            $html = "<span class=\"$this->cssClass\">";
            $html .= $formElement.'</span>';
        }
        return $html;
    }
    
  • To use this function, we add PHP code to our form like:
    <?php echo $f->formatOnError('name', '<i>Name:</i>') ?>
    
  • If there is no error, the code displays: Name:
  • Otherwise the HTML element appears within a span tag with a class set to error like:
    <span class="error">Name:</span>
    
  • By setting the CSS style to something like:
    .error {
      color: red;
      font-style: italic;
    ]
    
  • We get a distinctive style on error like: Name:
  • Another error reporting function is:
    function showMessageOnError($field, $formElement = "") {
        $html = $formElement;
        if (isset($this->errorList[$field])) {
            $errArray = $this->errorList[$field];
            $html = "<span class=\"$this->cssClass\">";
            $html .= $errArray["msg"].'</span>';
        }
        return $html;
    }
    
  • To use this function you use code like:
    <?php echo $f->showMessageOnError('name') ?>
    
  • If the error occurs the function displays the first error message
  • Otherwise it displays and empty string, which displays nothing at all
  • Thus, the error message only shows when an error occurs
  • You can see all the error handling code by clicking the link:
  • Note that you do not have to understand all the functions to use them
  • Instead, you only need to understand how to call them
  • To see how to call them, you can examine the form test code by clicking the link:

10.2.7: Saving Data and Finishing Up

  • After the form data is verified, it is time to save the data
  • We use the processData() function in our form page
    // Process the data
    function processData($f) {
        // Process the verified data here.
        // This is where you save data in the database.
    }
    
  • Within the processData() function we can save the form data to many locations
    • Databases
    • Cookies
    • Files
    • Session variables
    • URL strings
  • We know how to save data in the database
  • We will discuss other techniques in the future

Example of Saving Data in a Database

function saveData(&$f) {
    // Save the data;
    $name = $f->getValue("name");
    $sex = $f->getValue("sex");
    $state = $f->getValue("state");

    require "includes/dbconvars.php";
    $dbCnx = mysql_connect($dbhost, $dbuser, $dbpwd)
        or die(mysql_error());
    mysql_select_db($dbname, $dbCnx)
        or die(mysql_error());
    $sql = "
      INSERT INTO someTable(Name, Sex, State)
      VALUES ('$name', '$sex', '$state')
      ";

    // 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);
}

Finishing Up

  • Once the data is saved, you usually want to send the user to another page
  • For this you can use the redirect() function discussed in lesson 9.3.3
    function main($title = "") {
        $f = new FormVerifier();
        if (isset($_REQUEST["submitTest"])) {
            checkForm($f);
            if (!$f->isError()) { // data is OK
                saveData($f);
                redirect("echo.php?it=worked");
            }
        }
        include("includes/header.php");
        showContent($title, $f);
        include("includes/footer.php");
    }
    
  • Note the use of the CGI variable to forward information to the next page
  • Next week we will look at other techniques to forward data from one page to another

Exercise 10.2

In this exercise we explore how to use the FormVerifier class.

Specifications

  1. Verify the following files are installed in a subdirectory named includes of the phptest directory:

    If needed, change the dbconvars.php 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. Also, verify the following are installed in the indicated subdirectories of phptest:
  3. In addition, verify the echo.php page is installed in the phptest directory:
  4. Add the following file to the includes subdirectory of phptest:

    Copy the file and paste it into a text editor such as TextPad. After saving, verify the page saved without turning angle brackets and other special characters into HTML entities such as &lt; and &gt;.

  5. Copy the following page template into a text editor, save the file in your phptest directory as classyform.php, and then view the file as a Web page in your browser using localhost.
    <?php
    ob_start();
    
    include "includes/redirect.php";
    include "includes/formverifier.php";
    
    // Page starts and stops with this function call
    main("Classy Form");
    
    function main($title = "") {
        $f = new FormVerifier();
        if (isset($_REQUEST["submitTest"])) {
            checkForm($f);
            if (!$f->isError()) { // data is OK
                processData($f);
                redirect("echo.php?it=worked");
            }
        }
        include("includes/header.php");
        showContent($title, $f);
        include("includes/footer.php");
    }
    
    // Check the input form for errors
    function checkForm(&$f) {
        // Add code to test form values and record errors
    }
    
    // Process the data
    function processData($f) {
        // Process the verified data here.
        // This is where you save data in the database.
    }
    
    function showContent($title, $f) {
    ?>
    <h1><?php echo $title ?></h1>
    
    <?php echo $f->reportErrors() ?>
    <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 10.2.2: Form Page Organizations.

  6. Let us first add a form to the showContent() function at the bottom of the page. Replace the current HTML form 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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    
    <form action="<?php echo $_SERVER['PHP_SELF'] ?>"
      method="post">
    <fieldset>
    <legend>Enter your shipping information</legend>
    
    <table>
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('fname', 'First Name') ?>
    </td>
    <td class="inputcell">
      <input type="text" name="fname" size="35"
      value="<?php echo $f->getValue('fname') ?>">
      <?php echo $f->showMessageOnError('fname') ?>
    </td>
    </tr>
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('lname', 'Last Name') ?>
    </td>
    <td class="inputcell">
      <input type="text" name="lname" size="35"
      value="<?php echo $f->getValue('lname') ?>">
      <?php echo $f->showMessageOnError('lname') ?>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('street', 'Street') ?>
    </td>
    <td class="inputcell">
      <textarea name="street" cols="30">
    <?php echo $f->getValue('street') ?>
    </textarea>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('city', 'City') ?>
    </td>
    <td class="inputcell">
      <input type="text" name="city" size="35"
      value="<?php echo $f->getValue('city') ?>">
      <?php echo $f->showMessageOnError('city') ?>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('state', 'State') ?>
    </td>
    <td class="inputcell">
      <select name="state">
        <option value="">- Select One -</option>
        <option value="CA"
          <?php
            $value = $f->getValue('state');
            if ($value == 'CA') echo " selected";
          ?>>California</option>
        <option value="OR"
          <?php
            $value = $f->getValue('state');
            if ($value == 'OR') echo " selected";
          ?>>Oregon</option>
        <option value="WA"
          <?php
            $value = $f->getValue('state');
            if ($value == 'WA') echo " selected";
          ?>>Washington</option>
      </select>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('zip', 'ZIP') ?>
    </td>
    <td class="inputcell">
      <input type="text" name="zip" size="10"
      value="<?php echo $f->getValue('zip'); ?>">
      <?php echo $f->showMessageOnError('zip') ?>
    </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. However, we have updated it with PHP code to format errors and retain previous entries. For more information on retaining previous values see section 10.2.4: Class Design Overview. For more information on formatting errors see section 10.2.6: Error Tracking and Reporting.

    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.

  7. 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:
    $f->isEmpty('fname', "Please enter your first name.");
    $f->isEmpty('lname', "Please enter your last name.");
    $f->isEmpty('city', "Please enter a city.");
    $f->isEmpty('state', "Please select a state");
    $f->isNotInteger('zip', "Please enter a valid zip");
    

    For more information see section 10.2.5: Verifying Form Data.

  8. 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. Also notice that the errors are highlighted and values entered are retained. For more information see section 10.2.6: Error Tracking and Reporting.

  9. 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.

  10. 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)
    print_r($_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 10.2.7: Saving Data and Finishing Up.

  11. 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.

  12. 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.

  13. 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.

  14. Submit your final classyform.php file to Blackboard as part of assignment 10.

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

10.2.8: Summary

  • We created our FormVerifier class with:
    • A function to safely get form values
    • Error handling and reporting functions
    • Data verification functions
  • We encapsulated all the necessary variables and functions in the class
  • We also organized our form page using functions
  • The functions of our page template handle the sequence of form processing:
    • Controlling the page flow
    • Checking data
    • Saving data
    • Showing the form in a browser
  • Following this structure makes form handling faster and easier to develop

Further Information

Check Yourself

  1. True or false? Checking user input is a requirement for professional forms. (10.2.1)
  2. True or false? Checking user input with JavaScript means you do not need to check it on the server. (10.2.1)
  3. What PHP command can you use to determine the current page? (10.2.2)
  4. What is inheritance? (10.2.3)
  5. What code do you write for forms to retain entries when displaying error messages? (10.2.4)
  6. What is the advantage of using functions to verify form entries? (10.2.5)
  7. What code do you write for forms to highlight entries with errors? (10.2.6)
  8. What code do you write to examine a SQL statement before saving data in a database? (10.2.7)

10.3: Making Forms More Easily

Learner Outcomes

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

  • Use a class to create and display a form
  • Extend a class using inheritance
  • Code functions to display form elements

10.3.1: Problems with Repeated Code

  • In our formtest.php page, we had repeated code in the showContent() function:
    • HTML table tags <tr> and <td>
    • HTML form tags
    • PHP code to display previously-entered data
  • Repeating code such as this is error prone:
    • For example, we forget to update one part of a form element
    • Then the form works most of the time, but not always
    • We spend hours locating and correcting the bug
    • Then we find we need to change the form
    • But we forget to change one small part...
  • There are two techniques to remove repeated code
  • First we use loops to reduce the repeated code
  • Then we use functions to package the code so we can call it many times
  • Once the function is debugged, we can create new forms with fewer errors
  • We used this technique developing makeSelect() for selection lists in exercise 9.1
  • The following shows another example for making checkboxes

Example of Repeated Code in a Form

<tr>
  <td><?php echo $f->formatOnError('lang''<i>Languages:</i>'?></td>
  <td><input type="checkbox" name="lang[]" value="ASP"
     <?php
        $value 
$f->getValue('lang', array('ASP'));
        if (
$value and is_array($value) and in_array('ASP'$value)) {
            echo 
" checked";
        }
     
?>> ASP
  <input type="checkbox" name="lang[]" value="JSP"
     <?php
        $value 
$f->getValue('lang');
        if (
$value and is_array($value) and in_array('JSP'$value)) {
            echo 
" checked";
        }
     
?>> JSP
  <input type="checkbox" name="lang[]" value="PHP"
     <?php
        $value 
$f->getValue('lang');
        if (
$value and is_array($value) and in_array('PHP'$value)) {
            echo 
" checked";
        }
     
?>> PHP
  <input type="checkbox" name="lang[]" value="Other"
     <?php
        $value 
$f->getValue('lang');
        if (
$value and is_array($value) and in_array('Other'$value)) {
            echo 
" checked";
        }
     
?>> Other
</td>
</tr>

Example of Reducing Repeated Code Using a Loop

<tr>
  <td><?php echo $f->formatOnError('lang''<i>Languages:</i>'?></td>
  <td>
  <?php
    $values 
= array("ASP","JSP","PHP","Other");
    
$selected = array('PHP');
    foreach (
$values as $item) {
        echo 
"<input type=\"checkbox\" name=\"lang[]\" value=\"$item\"";
        
$list $f->getValue('lang'$selected);
        if (!
is_array($list)) $list = array($list);
        if (
in_array($item$list)) {
            echo 
" checked";
        }
        echo 
"> $item\n";
    }
  
?></td>
</td>
</tr>

10.3.2: Extending FormVerifier

  • To remove repeated code, we will create several functions to display form elements:
    • makeButton()
    • makeCheckBoxes()
    • makeHidden()
    • makeTextArea()
    • makeTextInput()
    • makePassword()
    • makeRadioGroup()
    • makeSelect()
  • To gain the benefits of OOP, we will encapsulate these functions in a new class: FormLib
  • Many of the functions will need to use the FormVerifier class
  • To enable our functions to work seamlessly with FormVerifier, we will use inheritance
    class FormLib extends FormVerifier
    
  • By extending from FormVerifier, we get to use all the variables and functions of FormVerifier
  • Following is the start of our new class: FormLib

Example Showing the Structure of FormLib

<?php
include_once("formverifier.php");

define("VERTICAL"1);
define("HORIZONTAL"2);

class 
FormLib  extends FormVerifier {
    
//---- private variables ----
    
private  $formLayout VERTICAL;

    
//---- General purpose functions ----

    // constructor
    
function __construct($cssClass="error"$layout=VERTICAL) {
        
parent::__construct($cssClass);
        
$this->formLayout $layout;
    }

    
//---- Form element functions ----
}
?>

Notes on the Code

  • We include formverifier.php so we can inherit from it:
    include_once("formverifier.php");
  • The function define() is used by PHP to define constant values
    • Constants help to document the code
  • Within class FormLib, we declare private variables and a constructor:
    private $formLayout = VERTICAL;
  • After this, we define the constructor for FormLib
  • The constructor uses the keyword parent to refer to the superclass: FormVerifier
  • We save the class in a file named formlib.php

10.3.3: Making Form Elements

  • Next step is to write code to display various form elements
  • In addition we code functions to make HTML for various form elements
  • The easiest functions are start() and finish

<?php
// Returns HTML to begin a form.
function start($method 'POST'$action ''$other '') {
    if (!
$action$action $_SERVER['PHP_SELF'];
    
$html "<form method=\"$method\" action=\"$action\"";
    if (
$other$html .= " $other";
    
$html .= ">\n";
    return 
$html;
}

// Returns HTML to end a form.
function finish() {
    return 
"</form>\n";
}
?>

  • Note the action parameter of the start() function
  • If no action is specified, the action is set to the current page:
    if (!$action) $action = $_SERVER['PHP_SELF'];
    
  • Other functions for displaying form elements could include:
    • makeButton()
    • makeCheckBoxes()
    • makeHidden()
    • makeTextArea()
    • makeTextInput()
    • makePassword()
    • makeRadioGroup()
    • makeSelect()
  • The instructor has written several functions that you can use, or you can write your own
    • If you find any errors, please report them
  • One of these functions is shown below along with example code to call the function
  • You can see all the functions by following the link: formlib.php

Example Function to Display HTML Check Boxes

<?php
// Return one or more checkbox HTML form controls.
function makeCheckBoxes($name$listPairs$selectList=null$other "") {
    
$selectList $this->getValue($name$selectList);
    
$html "";
    foreach (
$listPairs as $prompt => $value) {
        
$html .= "<input type=\"checkbox\" name=\"{$name}[]\" value=\"$value\"";
        if (
$other$html .= " $other";
        if (
$selectList AND in_array($value$selectList)) {
            
$html .= " checked";
        }
        
$html .= "> $prompt\n";
    }
    return 
$html;
}
?>

Example Code to Call the Function makeCheckBoxes()

<?php
  $list = array("ASP"=>"ASP", "JSP"=>"JSP",
                "PHP"=>"PHP", "Other"=>"Other");
  $selectList = array("PHP");
  echo $f->makeCheckBoxes('lang', $list, $selectList);
?>

10.3.4: Example Form Definition

  • Let us develop a page to test our FormLib class
  • To do so, we convert our formtest.php page and save it as formtest2.php
  • First we include formlib.php rather than formverifier.php:
    include_once("includes/formlib.php");
    
  • We modify the main function to instantiate a FormLib object:
    $f = new FormLib(HORIZONTAL);
    
  • Finally, we modify showContents() to make use of the new FormLib functions:

All in PHP

  • Another option is to make the entire form with PHP mode
  • You can see this in the following example:

Exercise 10.3

In this exercise we explore how to use the FormLib class to create forms.

Specifications

  1. Add the following file to the includes subdirectory of phptest:

    Copy the file and paste it into a text editor such as TextPad. After saving, verify the page saved without turning angle brackets and other special characters into HTML entities such as &lt; and &gt;.

  2. Without destroying your file, save the classyform.php file from the last exercise as classylib.php. View the file as a Web page using localhost.

    We will use the file as a starting point for exploring the FormLib class.

  3. At the top of classylib.php file but after the other include statements, add the following includes:
    include "includes/formlib.php";
    
  4. In the main() function, change the line that reads:
    $f = new FormVerifier();
    
    into a construction of a FormLib object using the following code:
    $f = new FormLib("error", HORIZONTAL);
    

    Reload (refresh) the page and notice the page still operates the same as with FormVerifier. This is because inheritance retains all the class variables and functions of the parent class. For more information about the design of FormLib see section 10.3.2: Extending FormVerifier.

  5. Let us change the showContent() function at the bottom of the page to make use of the FormLib class. Replace the current HTML form 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
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    
    <form action="<?php echo $_SERVER['PHP_SELF'] ?>"
      method="post">
    <fieldset>
    <legend>Enter your shipping information</legend>
    
    <table>
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('fname', 'First Name') ?>
    </td>
    <td class="inputcell">
    <?php echo $f->makeTextInput('fname', 35) ?>
    <?php echo $f->showMessageOnError('fname') ?>
    </td>
    </tr>
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('lname', 'Last Name') ?>
    </td>
    <td class="inputcell">
    <?php echo $f->makeTextInput('lname', 35) ?>
    <?php echo $f->showMessageOnError('lname') ?>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('street', 'Street') ?>
    </td>
    <td class="inputcell">
    <?php echo $f->makeTextArea('street', 5, 30) ?>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('city', 'City') ?>
    </td>
    <td class="inputcell">
    <?php echo $f->makeTextInput('city', 35) ?>
    <?php echo $f->showMessageOnError('city') ?>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('state', 'State') ?>
    </td>
    <td class="inputcell">
    <?php
    $list = array("- Select One -"=>"", "California"=>"CA",
        "Oregon"=>"OR", "Washington"=>"WA");
    echo $f->makeSelect('state', $list);
    ?>
    </td>
    </tr>
    
    <tr>
    <td class="labelcell">
    <?php echo $f->formatOnError('zip', 'ZIP') ?>
    </td>
    <td class="inputcell">
    <?php echo $f->makeTextInput('zip', 10) ?>
    <?php echo $f->showMessageOnError('zip') ?>
    </td>
    </tr>
    </table>
    </fieldset>
    
    <p id="formbuttons">
    <input type="button" name="prevb" value="Previous"
      onclick="history.back()">
    <?php echo $f->makeButton("Next") ?>
    </p>
    </form>
    

    Notice that this is the same form we have been working with. However, we have updated it to use the FormLib functions to create HTML elements. Notice how much shorter is the code for the form. Also, the FormLib functions automatically retain prior form entries. For more information see section 10.3.3: Making Form Elements.

  6. 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)
    print_r($_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 10.2.7: Saving Data and Finishing Up.

  7. Submit your final classylib.php file to Blackboard as part of assignment 10.

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

10.3.5: Summary

  • Using FormVerifier alone, we noticed repeating code in our forms
  • To reduce this repeating code, we developed a set of functions to display form elements
  • We developed FormLib as an extension of FormVerifier using inheritance
  • This allowed us to include all the data and functions of FormVerifier in FormLib
  • The complete FormLib code is available by clicking the link:
  • To demonstrate the use of FormLib, we rewrote our example form test code:

Check Yourself

  1. What are two ways to reduce repeated code? (10.3.1)
  2. Given the code:
    class FormLib extends FormVerifier {...}
    Which class is the superclass and which is the subclass? (10.3.2)
  3. What is the advantage of using functions to display HTML elements? (10.3.3)

Wrap Up

Due Next:
A10-Classy Forms (5/4/09)
Quiz 10 and Discussion Chapter 11 (5/4/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: November 03 2009 @22:38:41