Book HomePHP CookbookSearch this book

Chapter 9. Forms

Contents:

Introduction
Processing Form Input
Validating Form Input
Working with Multipage Forms
Redisplaying Forms with Preserved Information and Error Messages
Guarding Against Multiple Submission of the Same Form
Processing Uploaded Files
Securing PHP's Form Processing
Escaping Control Characters from User Data
Handling Remote Variables with Periods in Their Names
Using Form Elements with Multiple Options
Creating Dropdown Menus Based on the Current Date

9.1. Introduction

The genius of PHP is its seamless integration of form variables into your programs. It makes web programming smooth and simple, from web form to PHP code to HTML output.

There's no built-in mechanism in HTTP to allow you to save information from one page so you can access it in other pages. That's because HTTP is a stateless protocol. Recipe 9.2, Recipe 9.4, Recipe 9.5, and Recipe 9.6 all show ways to work around the fundamental problem of figuring out which user is making which requests to your web server.

Processing data from the user is the other main topic of this chapter. You should never trust the data coming from the browser, so it's imperative to always validate all fields, even hidden form elements. Validation takes many forms, from ensuring the data match certain criteria, as discussed in Recipe 9.3, to escaping HTML entities to allow the safe display of user entered data, as covered in Recipe 9.9. Furthermore, Recipe 9.8 tells how to protect the security of your web server, and Recipe 9.7 covers how to process files uploaded by a user.

Whenever PHP processes a page, it checks for GET and POST form variables, uploaded files, applicable cookies, and web server and environment variables. These are then directly accessible in the following arrays: $_GET , $_POST, $_FILES, $_COOKIE, $_SERVER, and $_ENV. They hold, respectively, all variables set by GET requests, POST requests, uploaded files, cookies, the web server, and the environment. There's also $_REQUEST, which is one giant array that contains the values from the other six arrays.

When placing elements inside of $_REQUEST, if two arrays both have a key with the same name, PHP falls back upon the variables_order configuration directive. By default, variables_order is EGPCS (or GPCS, if you're using the php.ini-recommended configuration file). So, PHP first adds environment variables to $_REQUEST and then adds GET, POST, cookie, and web server variables to the array, in this order. For instance, since C comes after P in the default order, a cookie named username overwrites a POST variable named username.

If you don't have access to PHP's configuration files, you can use ini_get( ) to check a setting:

print ini_get('variables_order');
EGPCS

You may need to do this because your ISP doesn't let you view configuration settings or because your script may run on someone else's server. You can also use phpinfo( ) to view settings. However, if you can't rely on the value of variables_order, you should directly access $_GET and $_POST instead of using $_REQUEST.

The arrays containing external variables, such as $_REQUEST, are superglobals. As such, they don't need to be declared as global inside of a function or class. It also means you probably shouldn't assign anything to these variables, or you'll overwrite the data stored in them.

Prior to PHP 4.1, these superglobal variables didn't exist. Instead there were regular arrays named $HTTP_COOKIE_VARS, $HTTP_ENV_VARS, $HTTP_GET_VARS, $HTTP_POST_VARS, $HTTP_POST_FILES, and $HTTP_SERVER_VARS. These arrays are still available for legacy reasons, but the newer arrays are easier to work with. These older arrays are populated only if the track_vars configuration directive is on, but, as of PHP 4.0.3, this feature is always enabled.

Finally, if the register_globals configuration directive is on, all these variables are also available as variables in the global namespace. So, $_GET['password'] is also just $password. While convenient, this introduces major security problems because malicious users can easily set variables from the outside and overwrite trusted internal variables. Starting with PHP 4.2, register_globals defaults to off.

With this knowledge, here is a basic script to put things together. The form asks the user to enter his first name, then replies with a welcome message. The HTML for the form looks like this:

<form action="/hello.php" method="post">
What is your first name?
<input type="text" name="first_name">
<input type="submit" value="Say Hello">
</form>

The name of the text input element inside the form is first_name. Also, the method of the form is post. This means that when the form is submitted, $_POST['first_name'] will hold whatever string the user typed in. (It could also be empty, of course, if he didn't type anything.)

For simplicity, however, let's assume the value in the variable is valid. (The term "valid" is open for definition, depending on certain criteria, such as not being empty, not being an attempt to break into the system, etc.) This allows us to omit the error checking stage, which is important but gets in the way of this simple example. So, here is a simple hello.php script to process the form:

echo 'Hello ' . $_POST['first_name'] . '!';

If the user's first name is Joe, PHP prints out:

Hello Joe!


Library Navigation Links

Copyright © 2003 O'Reilly & Associates. All rights reserved.