What We Will Cover
Elucidations
Homework Questions?
Quiz Questions?
^ top
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
|
^ top
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
^ top
10.1.2: Defining a Class
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
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
^ top
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
More Information
^ top
10.1.4: Class Functions
^ top
10.1.5: Coding Constructors
Example of a Constructor
function __construct($name, $pwd) {
$this->name = $name;
$this->pwd = $pwd;
$this->validated = false;
}
Constructors in PHP 4
Example Constructor in PHP 4
// Constructor
function User($name, $password) {
$this->name = $name;
$this->pwd = $pwd;
$this->validated = false;
}
More Information
^ top
10.1.6: Creating an Object and Calling a Function
- After designing the class, making use of one is simple:
- Construct an object
- 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:
- PHP sets aside memory space for all the member variables
- 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
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:

- 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
^ top
Exercise 10.1
In this exercise we code a PHP class and construct multiple objects.
Specifications
- Open the XAMPP Control Panel by double-clicking the icon on the desktop or by using the Apache Friends entry in the start menu.

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

- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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();
- Depending on the object you constructed, you should see output like:
Milk: Delicious moo juice! Bread: Hearty whole-grain goodness!
- 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.
^ top
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
- What are the main advantages of object-oriented PHP? (10.1.1)
- What keyword identifies the definition of a class? (10.1.2)
- Inside a class, what special variable is used to identify a class member? (10.1.2)
- What keyword identifies the declaration of a class variable? (10.1.3)
- What is meant by the term "information hiding"? (10.1.3)
- What is the interface of a class? (10.1.4)
- How does a member function differ from a nonmember function? (10.1.4)
- What is a constructor and what is its purpose? (10.1.5)
- How can you identify a constructor from all the other class functions? (10.1.5)
- Given a class named
Foo, what code do you write to construct an object of the class? (10.1.6)
- For the object declared in the previous question, what code do you write to call a public member function named bar()? (10.1.6)
^ top
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
|
^ top
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:
- The form is displayed and the user fills it in.
- The user submits the form to the server.
- If they left something out or provided invalid input, the form is redisplayed with the data that they already entered.
- The redisplayed form tells the user what is wrong and flags the incorrect fields.
- 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
^ top
10.2.2: Form Page Organization
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
}
?>
|
^ top
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:
- An array to hold a list of errors encountered during validation
- Other private data variables as needed
- General purpose functions such as constructors
- Functions to handle and report errors
- Functions to validate user-supplied data
- 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:
FormVerifier: first 5 items
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.
^ top
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
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;
}
?>
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. |
^ top
10.2.5: Verifying Form Data
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
^ top
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:
^ top
10.2.7: Saving Data and Finishing Up
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
^ top
Exercise 10.2
In this exercise we explore how to use the FormVerifier class.
Specifications
- 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.
- Also, verify the following are installed in the indicated subdirectories of phptest:
- In addition, verify the
echo.php page is installed in the phptest directory:
- 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 < and >.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
- 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.
^ top
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
- True or false? Checking user input is a requirement for professional forms. (10.2.1)
- True or false? Checking user input with JavaScript means you do not need to check it on the server. (10.2.1)
- What PHP command can you use to determine the current page? (10.2.2)
- What is inheritance? (10.2.3)
- What code do you write for forms to retain entries when displaying error messages? (10.2.4)
- What is the advantage of using functions to verify form entries? (10.2.5)
- What code do you write for forms to highlight entries with errors? (10.2.6)
- What code do you write to examine a SQL statement before saving data in a database? (10.2.7)
^ top
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
|
^ top
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>
^ top
10.3.2: Extending FormVerifier
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
^ top
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";
}
?>
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);
?>
^ top
10.3.4: Example Form Definition
All in PHP
- Another option is to make the entire form with PHP mode
- You can see this in the following example:
^ top
Exercise 10.3
In this exercise we explore how to use the FormLib class to create forms.
Specifications
- 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 < and >.
- 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.
- At the top of
classylib.php file but after the other include statements, add the following includes:
include "includes/formlib.php";
- 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.
- 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.
- 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.
- 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.
^ top
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
- What are two ways to reduce repeated code? (10.3.1)
- Given the code:
class FormLib extends FormVerifier {...}
Which class is the superclass and which is the subclass? (10.3.2)
- What is the advantage of using functions to display HTML elements? (10.3.3)
^ top
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
^ top
Home
| WebCT
| Announcements
| Course info
| Expectations
| Schedule
Project
| Help
| FAQ's
| HowTo's
| Links
Last Updated: November 03 2009 @22:38:41
|