PHP – Handling form data

Today I will explain how I handle submitted form information in PHP so the information is secure and the values are consistant.

The Problem
Handling form data in PHP can become very hairy. Originally, PHP was simple. It was intended to take data submitted from a form and insert it into a MySQL database. Many basic features were added early on to make this as easy as possible such as adding special slashes (magic quotes) to strings and making the values readily available by making them globally registered. These features added security problems and complexity once PHP grew beyond the realm of MySQL databases.

Each of the methods I describe have some advantages and disadvantages. Hopefully these techniques will be useful for you as they are for me.

Method one, unset() first
It is a good idea to initially unset all your variables that you want to initialize from submitted data. The reason is security. For example, say your web server has the register globals enabled. This means the value will be defined and set before the first line of your PHP will be executed. Normally this variable may only have a few actual valid values that you restrict the user to by creating a list box in your HTML form. With registered globals, a user could pass that variable with a value that you did not intend by simply calling your script with a get query string, eg: script.php?Var=20. You could check that $Var is a valid value by checking it with some logic, but the easiest way is to simply get the value as it was intended to be submitted from one of the PHP predefined variable arrays $_POST or $_GET.

Example:[php]
unset($Var);
if( isset($_POST[‘Var’]) )
$Var = $_POST[‘Var’];

if( isset($Var) )
{

}[/php]This method has an advantage that no matter how the Var was originally declaired globally, it is imediately unset and reinitialized only if the Var came from the POST method.

Disadvantage: This method does not deal with values that may be escaped with slashes. It also requires constant checking if the value is set before using it. I recommend this style when handling very important information such as passwords or uploaded files.

Initialize all variables at the top of your script
This method is easy to do and is the most common method I use when writing simple PHP scripts. This removes the need to constantly check if the value isset() since your values will be set to something.

Example:[php]
$Var= 10;
if( isset($_POST[‘Var’]) )
$Var = $_POST[‘Var’];

$query = “SELECT * FROM table WHERE id = $Var”;
…[/php]This methods advantage is you no longer have to check that $Var is set to a value. It may, however be an incorrect value but it will not give you a warning that you are using an undefined variable.

Disadvantage: This method does not deal with values that may be escaped with slashes. If the value is incorrect, you will may still receive a warning or error when you use the variable in your code. I recommend this method for handling data in a setting where you are not concerned with security.

Handling magic quoted values
PHP may handles submitted data in a way that you may not expect. A feature called magic quotes will take the values of submitted data and add slashes to quotes and other unique characters. These slash escaped strings are wonderful when formatting the values for queries on a MySQL database. They, however, have other real valuable use. It is now recommended that this feature should not be used. Since it is a common feature though, the feature is usually enabled on most web servers. Changing this one setting could break numbers of PHP scripts. With this in mind, we must develop methods to deal with it in both cases.

Example:[php]
$Var = “”;
// Check if the value was posted and is escaped by the magic quotes
if( isset($_POST[‘Var’]) && get_magic_quotes_gpc() )
$Var = stripslashes( $_POST[‘Var’] );
// Else check if the value was posted
else if( isset($_POST[‘Var’]) )
$Var = $_POST[‘Var’];
…[/php]
Now your variable’s value is exactly what was intended to be submitted to the server without any extra slashes.

Note: You must now remember to call the function addslashes() when using the values in queries for MySQL. The advantage here is you no longer have to check if the value should have slashes added, you can now assume it always does.

Disadvantage: This method requires a lot of lines of code to get the data in a sterized state. I recommend this method for handling 1-5 submitted values.

Simplification
When writing PHP code that can become complex or used on a variety of different web servers, it is important to simplify the code where possible. To do this, you can create your own library of methods to initialize and escape your variables. These methods help prevent malicious usage of your scripts.

My technique is to create and use functions to initialize your values.[php]
function PostVar($Name, $Default = false, $RemoveSlashes = true )
{
if( isset($_POST[$Name]) )
{
if( get_magic_quotes_gpc() && $RemoveSlashes )
return stripslashes($_POST[$Name]);
return $_POST[$Name];
}
return $Default;
}

$SearchVar = PostVar(‘SearchText’, ”, false);
$Password = PostVar(‘Password’, false, true);
$Email = PostVar(‘Email’, ‘default@host.com’, true);

$query = ‘SELECT password, email FROM accounts WHERE name LIKE ‘. $SearchVar;
$result = mysql_query($query, GetMyConnection() );
$Row = mysql_fetch_array($result);
if( $Row[‘password’] == $Password )
{
mail($Email, ‘Latest Scores’, ‘You latest score average is ‘. $Row[‘average_score’]);
echo “Successfully sent latest scores to $Email.”;
}
else
{
echo “Error sending latest scores to $Email.”;
}[/php]
As you can see, the submitted field ‘SearchText’ did not have the magic quotes removed since we are using it in a MySQL query. Fields ‘Password’ and ‘Email’ do have the slashes removed from the values since we do not want any slashes screwing up our script later on. The default values are used if the fields were not posted. Note the value for the query is an empty string which will not give us negative effects when used in a query. The default value for the password is false, in this case we can presume a password from the database will always have a value there for it prevents accidental cases that may arise. The default value for the Email variable allows us to send the E-mail to a valid address in the event no Email address was submitted.

These concepts should assist you in intializing and using variables that come from forms. Next blog I will explore the power of using arrays to handle submitted form data to simplify creating database queries.