More Books
PHP 5 Unleashed
PHP 5 Unleashed
Table of Contents
Copyright
Lead Author
Contributing Authors
Acknowledgments
We Want to Hear from You!
Reader Services
Introduction
Organization of the Book
Part I. Working with PHP for General Web Development
Chapter 1. Basic PHP Development
How PHP Scripts Work
Basic PHP Syntax
Basic PHP Data Types
Variable Manipulation
Control Structures
User-Defined Functions
Dynamic Variables and Functions
Multiple File PHP Scripts
References
Strings in PHP
Comparing Strings
Advanced String Comparison
Search and Replacement
Formatting Strings
Strings and Locales
Formatting Date and Time Values
Summary
Chapter 2. Arrays
Basic Arrays
Implementing Arrays
More Array Materials
Chapter 3. Regular Expressions
The Basics of Regular Expressions
Limitations of the Basic Syntax
POSIX Regular Expressions
Perl-Compatible Regular Expressions (PCRE)
PCRE Modifiers
A Few Final Words
Chapter 4. Working with Forms in PHP
HTML Forms 101
Working with Form Submissions in PHP
Summary
Chapter 5. Advanced Form Techniques
Data Manipulation and Conversion
Form Data Integrity
Form Processing
Summary
Chapter 6. Persistent Data Using Sessions and Cookies
HTTP Cookies
PHP Sessions
Advanced Sessions
Summary
Chapter 7. Using Templates
The What and Why of Templates
The Smarty Template Engine
Summary
Part II. Advanced Web Development
Chapter 8. PEAR
What Is PEAR?
Getting and Installing PEAR
Using the PEAR Package Manager
Using the PEAR Website
Using PEAR Packages in Applications
Summary
Reference
Chapter 9. XSLT and Other XML Concerns
Relating XML to HTML
Using XSLT to Describe HTML Output Using XML Input
PHP4 and XSLT Using the DOM XML Module
PHP4 and XSLT Using the XSLT Module
PHP5 and XSLT
Accessing XML Data Using SimpleXML
Generating XML Documents Using PHP
Summary
References
Chapter 10. Debugging and Optimizations
Debugging Your PHP Scripts
Optimizing Your PHP Scripts
Summary
Chapter 11. User Authentication
Authenticating Users in PHP
Securing PHP Code
Summary
Chapter 12. Data Encryption
Shared Secret Versus Public Key
Shared Secret Algorithms
Public Key Cryptography
Using Public Keys in PHP
Summary
Chapter 13. Object-Oriented Programming in PHP
Why Objects?
Creating Basic Classes
Advanced Classes
Special Methods
Class Autoloading
Object Serialization
Exceptions
Iterators
Summary
Chapter 14. Error Handling
The PHP Error-Handling Model
What to Do About Errors
The Default Error Handler
Error Suppression
Custom Error Handlers
Causing Errors
Putting It All Together
Summary
Chapter 15. Working with HTML/XHTML Using Tidy
Introduction
Basic Tidy Usage
Tidy Configuration Options
Using the Tidy Parser
Applications of Tidy
Summary
Chapter 16. Writing Email in PHP
The MIME Protocol
Implementing MIME Email in PHP
Summary
Part III. Building Applications in PHP
Chapter 17. Using PHP for Console Scripting
Core CLI Differences
Working with PHP CLI
CLI Tools and Extensions
Summary
Chapter 18. SOAP and PHP
What Are Web Services?
Installation
Creating Web Services
Consuming Web Services
Looking for Web Services
Summary
Chapter 19. Building WAP-Enabled Websites
What Is WAP?
System Requirements
Introduction to WML
Serving WAP Content
Sample Applications
Summary
Part IV. I/O, System Calls, and PHP
Chapter 20. Working with the File System
Working with Files in PHP
File Permissions
File Access Support Functions
Summary
Chapter 21. Network I/O
DNS/Reverse DNS Lookups
Socket Programming
Network Helper Functions
Summary
Chapter 22. Accessing the Underlying OS from PHP
Introduction
Unix-Specific OS Functionality
Platform-Independent System Functions
A Brief Note About Security
Summary
Part V. Working with Data in PHP
Chapter 23. Introduction to Databases
Using the MySQL Client
Basic MySQL Usage
Summary
Chapter 24. Using MySQL with PHP
Performing Queries from PHP
A MySQLi Session Handler
What Is a Custom Session Handler?
Summary
Chapter 25. Using SQLite with PHP
What Makes SQLite Unique?
Basic SQLite Functionality
Working with PHP UDFs in SQLite
Odds and Ends
Summary
Chapter 26. PHP's dba Functions
Preparations and Settings
Creating a File-Based Database
Writing Data
Reading Data
Sample Application
Conclusion
Part VI. Graphical Output with PHP
Chapter 27. Working with Images
Basic Image Creation Using GD
Using the PHP/GD Drawing Functions
Working with Colors and Brushes
Using Fonts and Printing Strings
General Image Manipulation
Other Graphics Functions
Summary
Chapter 28. Printable Document Generation
A Note Regarding the Examples in This Chapter
Generating Dynamic RTF Documents
Generating Dynamic PDF Documents
Related Resources
Part VII. Appendixes
Appendix A. Installing PHP5 and MySQL
Installing PHP5
Installing MySQL and PHP Modules
Installing PEAR
Appendix B. HTTP Reference
What Is HTTP?
PHP Programming Libraries for HTTP Work
Understanding an HTTP Transaction
HTTP Client Methods
What Comes Back: Server Response Codes
HTTP Headers
Encoding
Identifying Clients and Servers
The "Referer"
Fetching Content from an HTTP Source
Media Types
Cookies: Preserving State and a Tasty Treat
Security and Authorization
Client-Side Caching of HTTP Content
Appendix C. Migrating Applications from PHP4 to PHP5
Configuration
Object-Oriented Programming (OOP)
New Behavior of Functions
Further Reading
Appendix D. Good Programming Techniques and Performance Issues
Common Style Mistakes
Common Security Concerns
Style and SecurityLogging
Summary
Appendix E. Resources and Mailing Lists
Relevant Websites
Mailing Lists and Newsgroups
Index
SYMBOL
A
B
C
D
E
F
G
H
I
J
K
L
M
N
O
P
Q
R
S
T
U
V
W
X
Y
Z

Working with Form Submissions in PHP

Now that you have been introduced to all the different HTML widgets (or if you happened to skip ahead because you knew of them already) it's time to get into the real PHP-related materials of the chapter. The remainder of this chapter will be focused on accessing and working with form (and related) data.

Retrieving Form Values

After a form has been submitted back to the Web server, if the ACTION attribute of the form is a PHP script, that script is executed and is provided the data that was submitted. But how is this data accessed from within PHP? Thankfully, there are a number of very convenient methods to use when retrieving data.

Depending on what method was used to submit the form data to the PHP script (GET or POST), PHP has two superglobal arrays, called $_GET and $_POST, respectively, that will be used to store this data. These variables are associate arrays containing a list of keys (representing the names of the form elements as specified by their NAME attribute) and their associated values. Hence, the value of the $_GET['mytext'] variable will contain the value of the HTML widget whose NAME attribute is mytext:

The HTML widget:

<INPUT TYPE="text" NAME="mytext" VALUE="This is my text!">

The PHP code:

<?php echo $_GET['mytext']; ?>

Output when the form is submitted:

This is my text!

NOTE

The term superglobal was introduced in Chapter 1 and indicates that regardless of the current scope (in a function, for example) the variables $_GET and $_POST will always be available without having to use the global statement to bring them into the current scope. See Chapter 1 for more information.


Using the $_GET array assumes that the form was submitted via the GET method. If the submission was done via the POST method, the data would be stored in the $_POST variable instead. For those circumstances when the method that the data was submitted through is irrelevant (or could be either), a third superglobal array, $_REQUEST, is provided, which combines $_GET, $_POST, $_COOKIE (the superglobal containing cookie variablessee Chapter 5, "Advanced Form Techniques"), and $_FILES (discussed later in the chapter).

For those who have worked with PHP in the past (prior to PHP version 4.1.0), by default, PHP created standard variable names such as $myvalue to represent the value contained within the $_GET['myvariable'] superglobal. Although it is still possible to turn this behavior on by default (by setting the register_globals directive to on), doing so is highly discouraged because of security issues. A much safer approach (accomplishing the same end result) is to use the import_request_variables() function. This function will create global-scope variables such as $myvalue for the values stored in the relevant superglobal arrays. The syntax for this function is as follows:

import_request_variables($types [, $prefix])

When using this function, $types represents a string indicating the types of variables to import and should consist of any combination (not case sensitive) of the letters P, G, and C. These letters represent $_POST, $_GET, and $_COOKIE, respectively. The second optional parameter, $prefix, if provided, should be a string representing what to prefix to the start of every variable created.

In Listing 4.11, assuming that $_GET['myvalue'] exists, you can use the import_request_variables() function to create a local copy of it, as shown:

Listing 4.11. Using the import_request_variables() Function
<?php
    /* Assume $_GET['myvalue'] exists */
    import_request_variables("G", "myget_");
    echo "The value of the 'myvalue' field is: $myget_myvalue";
?>

NOTE

import_request_variables() is recommended over the use of the register_globals configuration directive; however, note that it does not protect you from the security risks associated with working with user data. It is always recommended that data received from the user be sanitized before use. It is also important to note that the import_request_variables() function imports variables into the global scope only. Thus, it should never be used from within a function.


Data-Access "Gotchas"

Now that you have an understanding of how to access external input from your PHP script, a number of small issues may arise in your attempts to work with this knowledge. To save you time, I'll outline these issues, starting with HTML widgets whose name contains a period.

In HTML, it is perfectly acceptable to have a form widget named myvar.email (the value set for the widget's NAME tag). However, recalling the restrictions placed on variable names described in Chapter 1, such a variable name is invalid in PHP. As a consequence, when PHP is provided a form submission that contains a period in one or more of the widget's names, they are converted to an underscore character automatically.

Therefore, this widget's value

<INPUT TYPE="text" NAME="myform.email">

would be accessed in PHP as the following:

<?php
    echo $_GET['myform_email']; 
?>

Although every form can be designed in such a way that no widget is given a name with a period in it, this behavior in PHP is important when dealing with image submission widgets. If an image widget has a NAME attribute, when clicked, it sends as part of the form data the X,Y coordinate of where the user clicked the image. Specifically, the image widget will send these values in the variables AAAAAA.x and AAAAAA.y, where AAAAAA represents the value of the NAME attribute. Thus, to access these values in PHP, the period must be substituted with an underscore as shown:

The image submission widget:

<INPUT TYPE="image" src="images/myimagemap.gif" NAME="mymap">

How to access the coordinates from PHP:

<?php echo "X Coordinate: {$_GET['mymap_x']}<BR>
            Y Coordinate: {$_GET['mymap_y']}"; ?>

While I am discussing using the image widget in PHP scripts, I want to point out another common coding mistake in its use. In situations where it would be desirable to have multiple submission widgets for the same form, each submission widget must be given a unique value for its NAME attribute to distinguish each from the other. If the image submission widget is used, often either one or the other X,Y variable is checked to determine which submission image was clicked, using a facility such as if($_GET['myimagename_x']). Unfortunately, this method is the incorrect way to do things. As you know, an image submit widget returns the X,Y values where the user clicked the image to the PHP script. The problem is that the preceding if statement example will fail if the X value returned is 0 (if using a text-based browser, the X,Y coordinate will always be returned as 0,0 when clicked). A much more reliable method is to use the isset() function, as shown in Listing 4.12:

Listing 4.12. Properly Checking for Submission Using Image Widgets

The HTML image submission widgets:

<INPUT TYPE="image" NAME="submit_one" src="/images/button1.gif">
<INPUT TYPE="image" NAME="submit_two" src="/images/button2.gif">

Properly determining which submission button was clicked in PHP:

<?php
     if(isset($_GET['submit_one_x'])) {

          /* code if the first submit button was pressed */ 

     } elseif(isset($_GET['submit_two_x'])) {
               /* code if the second submit button was pressed */
     } else {

          /* Code if neither submit was pressed */
     }
?>

NOTE

In Listing 4.12, notice that I have included a third case (the last else statement). If there are only two Submit buttons (such as in this example) and both are checked, will the code in the else statement ever be executed? Yes! In Microsoft Internet Explorer, pressing the Enter key while focused on certain widgets (such as a text field) will cause the form to be submitted without either image submit widget being used.


Using Arrays as Widget Names

As I described in the first section of this chapter, the <SELECT> widget can potentially be used to select multiple items and thus have multiple values to pass to PHP. Unfortunately, setting the NAME attribute to something such as myselect will create a variable $_GET['myselect'], which will contain only the last item selected from the list. Obviously, this is not the desired result and another method must be used. To solve this problem, PHP allows you to dynamically create arrays based on form submissions by appending a set of square brackets [] to the end of the name of the widget. Thus, myselect would become myselect[], causing PHP to create an additional item in the array $_GET['myselect'] instead of overwriting the previous value. This concept is illustrated in Listing 4.13:

Listing 4.13. Using Arrays with Form Data in PHP

The HTML code:

<SELECT NAME="myselect[]" MULTIPLE SIZE=3>
<OPTION VALUE="value1">Pick Me!</OPTION>
<OPTION VALUE="value2">No, Pick Me!</OPTION>
<OPTION VALUE="value3">Forget them, pick me!</OPTION>
<OPTION VALUE="value4">Pick me, I'm the best</OPTION>
</SELECT>

The PHP code to access which value(s) were selected:

<?php
     foreach($_GET['myselect'] as $val) {
          echo "You selected: $val<BR>";
     }
     echo "You selected ".count($_GET['myselect'])." Values.";
?>

This technique is not limited to <SELECT> widgets or, for that matter, integer-based arrays. If you would like to provide a string key for a given form widget, specify it (without quotes) within the square brackets:

<INPUT TYPE="text" NAME="data[email]" VALUE="joe.doe@joe.doe.com">

When submitted, the preceding text field's value could be accessed by using $_GET['data']['email'].

Handling File Uploads

NOTE

For file uploading to work properly in PHP, a number of configuration directives should be appropriately set in the php.ini file. Specifically, the file_uploads, uploads_max_filesize, upload_tmp_dir, and post_max_size directives affect PHP's capability to receive uploaded files. For information on these directives, please consult the PHP manual.


As I alluded to in the first section of this chapter, PHP is capable of accepting file uploads from HTML forms via the file widget. When uploading files from an HTML form, some special consideration must be taken regarding the <FORM> tag itself. Specifically, for the file upload to succeed, the ENCTYPE attribute of the <FORM> tag must be set to the MIME value multipart/form-data and the METHOD attribute must be set to POST. An example of an HTML form that uploads a file to the script upload.php is shown in Listing 4.14:

Listing 4.14. Setting Up the HTML to Upload a File via HTTP
<FORM METHOD="POST" ACTION="upload.php" ENCTYPE="multipart/form-data">
<INPUT TYPE="file" NAME="myfile"><BR>
<INPUT TYPE="submit" VALUE="Upload the file">
</FORM>

NOTE

A special hidden form widget with the name MAX_FILE_SIZE may be used to specify the maximum file size accepted for the file upload. This size restriction is enforced on the client side and may not work for all clients. This check along with the upload_max_filesize configuration directive should be used.


When the form in Listing 4.14 is submitted, the file will be uploaded to the Web server and stored in a temporary directory specified by the upload_tmp_dir php.ini directive. PHP then creates a superglobal variable, $_FILES, and, in this case, populates the $_FILES array with a key myfile. The value of this key is another array populated with information about the file that was uploaded. Specifically, the array stored in $_FILES['myfile'] has the keys shown in Table 4.7.

Table 4.7. Keys Created for a File When Uploaded

name

The name of the file as it was on the client machine

type

The MIME type for the file if known

size

The size of the uploaded file in bytes

tmp_name

The temporary name given to the file by PHP when it was uploaded to the server

error

An integer value representing the error that occurred while uploading the file


NOTE

The following array keys may or may not contain a value, depending on the circumstances under which the file was uploaded. For instance, the type key may be empty if the browser did not provide any MIME information.


If an error has occurred during the uploading of the file, $_FILES['myfile']['error'] will be set to an integer representing the error that occurred and representing one of the following constants:

Table 4.8. File Uploading Error Constants in PHP

UPLOAD_ERR_OK

No error occurred.

UPLOAD_ERR_INI_SIZE

The uploaded file exceeds the maximum value specified in the php.ini file.

UPLOAD_ERR_FORM_SIZE

The uploaded file exceeds the maximum value specified by the MAX_FILE_SIZE hidden widget.

UPLOAD_ERR_PARTIAL

The file upload was canceled and only part of the file was uploaded.

UPLOAD_ERR_NOFILE

No file was uploaded.


Assuming the file was uploaded successfully, it must be moved from its current location (the temporary directory) to its permanent location. If the file is not moved, it will be deleted when the PHP script's execution is complete.

Because of security issues, prior to moving the file from its temporary location to a new one, the is_uploaded_file() should be used to confirm that the file was actually uploaded through PHP. After the file has been confirmed, the move_uploaded_file() can be used to move the uploaded file from its current location to a new one. To move the file to the destination directory, PHP must also have write permission for that directory. See Chapter 21, "Working with Streams and the File System," for detailed information on the use of file-uploading related functions and working with permissions.

NOTE

The move_uploaded_file() function assumes the file is stored in the directory specified by the upload_tmp_dir configuration directive.


Listing 4.15 processes the file uploaded in the example described in Listing 4.14:

Listing 4.15. Processing a File Upload in PHP
<?php
     if(is_uploaded_file($_FILES['myfile']['tmp_name'])) {
          move_uploaded_file($_FILES['myfile']['tmp_name'], 
          "/path/to/dir/newname");
     }
?>