আগামী ৩০ নভেম্বর-২০১৭ তারিখ থেকে শুরু হচ্ছে পাঁচ মাস ব্যাপী Professional Web Design and Development with HTML, CSS PHP,MySQL,JavaScript, AJAX, JQUERY, Bootstrap and Live Project কোর্সের ৮৭ তম ব্যাচ এবং ৫ ডিসেম্বর-২০১৭ তারিখ থেকে শুরু হচ্ছে চার মাস ব্যাপী Zend PHP-7 Certified PHP Engineering (Advance PHP) কোর্সের ৩৫ তম ব্যাচ। প্রত্যেকটি কোর্স এর ফী নির্ধারণ করা হয়েছে ৩০,০০০/= আগ্রহীদেরকে অতিসত্বর মাসুদ আলম স্যার এর সাথে যোগাযোগ করতে অনুরোধ করা যাচ্ছে। স্যার এর মোবাইল: 01722 81 75 91

Sanitize and Validate Data with PHP Filters

This tutorial will explain some methods of Getting Clean With PHP: Data Sanitization and Validation by focusing on several different forms of data inputs and how to use PHP filters and custom functions.

Sanitize and Validate Data With PHP

Why Sanitize and Validate?

In this tutorial, we are really focused on data inputs that users or external sources may provide. This means that we do not control the data we are receiving. All we can do is control what is done with it after we receive it. There are all sorts of threats related to data security from user-inputs and third-party data.

Some un-popular data security threats:

  • Cross-Site Scripting (XSS): A form of code injection where a script is injected onto a website from a completely different website. This is by far the most common security vulnerability online.
  • SQL Injection: The second most common security vulnerability online, this is another form of code injection in which a script is used to participate in one of numerous exploitative behaviors including (but not limited to) exposing and/or gaining unauthorized access to data, altering data inside of a database, or simply injecting code to be rendered or executed within a website thereby breaking or altering the website.
  • Cross-Site Request Forgery (CSRF/XSRF): A less common exploit that relies more on data sources like browser and session cookies than poorly sanitized and validated data inputs, CSRF (pronounced “sea-surf”) can be used to execute commands on a website without the user’s permission. One popular CSRF method is using an improperly formed image data URI or src value to execute a script instead of displaying an image.
  • Improper Data: Not really a “security vulnerability” per se, improper data can cause hosts of problems for a website owner or database administrator. Often, improper data can break poorly coded websites or cause automated systems to crash. An example of this was the ability to alter entire MySpace profile pages by posting using all sorts of HTML/CSS hackery.

For our purposes, we are going to only focus on server-side methods of improving data security with PHP, so let’s see how the terms “sanitization” and “validation” are defined with relation to PHP. According to the PHP manual:

Note:

Validation is used to validate or check if the data meets certain qualifications. For example, passing in FILTER_VALIDATE_EMAIL will determine if the data is a valid email address, but will not change the data itself.

Sanitization will sanitize the data, so it may alter it by removing undesired characters. For example, passing in FILTER_SANITIZE_EMAIL will remove characters that are inappropriate for an email address to contain. That said, it does not validate the data.

Essentially, if your website is the nightclub that everybody wants to get into, validation checks the guest list and IDs at the door while sanitization acts as the bouncer that throws out any undesirables that happen to squeak past. With this in mind, let’s take a look at PHP Filters Extension.

What Filters Do I Have?

All PHP installations are not created equal. While PHP 5.2.0 was the introduction of filters, not all installations have the same set of filters in their Filters Extension. Most installations will have all of the filters we’re going to go over, but to teach you a bit about the Filters Extension, we’re going to find out just what you have on your server. In the source download, I have included a file called getfilters.php that, once installed and run on your server, will display all of your filters (both data filters available through the filter_var function and stream filters available through stream_filter_append).

First, we get the array containing the list of all available filters with filter_list, then we loop through the array and echo out the filter name, find out the filter’s assigned ID, and echo this ID as well.

How Do I Use A Filter?

PHP Filters for validation and sanitization are activated by passing at least two values to the PHP Filters Extension function filter_var. As an example, let’s use the Sanitize Filter for an Integer number like so:


<?php

$value = '123abc456def';

echo filter_var($value, FILTER_SANITIZE_NUMBER_INT);

?>

In the example, we have a variable $value that is passed through the Filters Extension function filter_var using the FILTER_SANITIZE_NUMBER_INT filter. This results in the following output:

123456

What Do The Different Filters Do?

The list below is not complete, but it does contain the majority of the filters that come standard with 5.2.0+ installations. Custom filters and those added from custom extensions are not included here.

FILTER_VALIDATE_BOOLEAN: Checks whether or not the data passed to the filter is a boolean value of TRUE or FALSE. If the value is a non-boolean value, it will return FALSE. The script below would echo “TRUE” for the example data $value01 but would echo “FALSE” for the example data $value02:


<?php

$value01 = TRUE;

if(filter_var($value01,FILTER_VALIDATE_BOOLEAN)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

echo '<br /><br />';

$value02 = TRUE;

if(filter_var($value02,FILTER_VALIDATE_BOOLEAN)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

?>

FILTER_VALIDATE_EMAIL: Checks whether or not the data passed to the filter is a potentially valid e-mail address. It does not check whether the e-mail address actually exists, just that the format of the e-mail address is valid. The Script below would echo “TRUE” for the example data $value01 but would echo “FALSE” for the example data $value02 (because the second lacks the required @domain.tld portion of the e-mail address):


<?php

$value01 = 'test@example.com';

if(filter_var($value01,FILTER_VALIDATE_EMAIL)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

echo '<br /><br />';

$value02 = 'test';

if(filter_var($value02,FILTER_VALIDATE_EMAIL)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

?>

FILTER_VALIDATE_FLOAT: Checks whether or not the data passed to the filter is a valid float value. The Script below would echo “TRUE” for the example data $value01 but would echo “FALSE” for the example data $value02 (because comma separators are not allowed in float values):


<?php

$value01 = '1.234';

if(filter_var($value01,FILTER_VALIDATE_FLOAT)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

echo '<br /><br />';

$value02 = '1,234';

if(filter_var($value02,FILTER_VALIDATE_FLOAT)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

?>

FILTER_VALIDATE_INT: Checks whether or not the data passed to the filter is a valid integer value. The Script below would echo “TRUE” for the example data $value01 but would echo “FALSE” for the example data $value02 (because fractions / decimal numbers are not integers):


<?php

$value01 = '123456';

if(filter_var($value01,FILTER_VALIDATE_INT)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

echo '<br /><br />';

$value02 = '123.456';

if(filter_var($value02,FILTER_VALIDATE_INT)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

?>

FILTER_VALIDATE_IP: Checks whether or not the data passed to the filter is a potentially valid IP address. It does not check if the IP address would resolve, just that it fits the required data structure for IP addresses. The Script below would echo “TRUE” for the example data $value01 but would echo “FALSE” for the example data $value02:


<?php

$value01 = '192.168.0.1';

if(filter_var($value01,FILTER_VALIDATE_IP)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

echo '<br /><br />';

$value02 = '1.2.3.4.5.6.7.8.9';

if(filter_var($value02,FILTER_VALIDATE_IP)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

?>

FILTER_VALIDATE_URL: Checks whether or not the data passed to the filter is a potentially valid URL. It does not check if the URL would resolve, just that it fits the required data structure for URLs. The Script below would echo “TRUE” for the example data $value01 but would echo “FALSE” for the example data $value02:


<?php

$value01 = 'http://w3programmers.com';

if(filter_var($value01,FILTER_VALIDATE_URL)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

echo '<br /><br />';

$value02 = 'nettuts';

if(filter_var($value02,FILTER_VALIDATE_URL)) {

echo 'TRUE';

} else {

echo 'FALSE';

}

?>

FILTER_SANITIZE_STRING: By default, this filter removes any data from a string that is invalid or not allowed in that string. For example, this will remove any HTML tags, like <script> or <strong> from an input string:


<?php

$value = "<script>alert('TROUBLE HERE');</script>";

echo filter_var($value, FILTER_SANITIZE_STRING);

?>

This script would remove the tags and return the following:

alert(‘TROUBLE HERE’);

FILTER_SANITIZE_ENCODED: Many programmers use PHP’s urlencode() function to handle their URL Encoding. This filter essentially does the same thing. For example, this will encode any spaces and/or special characters from an input string:


<?php

$value = "<script>alert('TROUBLE HERE');</script>";

echo filter_var($value, FILTER_SANITIZE_ENCODED);

?>

This script would encode the punctuation, spaces, and brackets, then return the following:

%3Cscript%3Ealert%28%27TROUBLE%20HERE%27%29%3B%3C%2Fscript%3E

FILTER_SANITIZE_SPECIAL_CHARS: This filter will, by default, HTML-encode special characters like quotes, ampersands, and brackets (in addition to characters with ASCII value less than 32). While the demo page does not make it abundantly clear without viewing the source (because the HTML-encoded special characters will be interpreted and rendered out), if you take a look at the source code you’ll see the encoding at work:


<?php

$value = '<script>alert("TROUBLE HERE");</script>';

echo filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS);

?>

It converts the special characters into their HTML-encoded selves:

&#60;script&#62;alert(&#39;TROUBLE HERE&#39;);&#60;/script&#62;

FILTER_SANITIZE_EMAIL: This filter does exactly what one would think it does. It removes any characters that are invalid in e-mail addresses (like parentheses, brackets, colons, etc). For example, let’s say you accidentally added parentheses around a letter of your e-mail address (don’t ask how, use your imagination):


<?php

$value = 't(e)st@example.com';

echo filter_var($value, FILTER_SANITIZE_EMAIL);

?>

It removes those parentheses and you get your beautiful e-mail address back:

test@example.com

This is a great filter to use on e-mail forms in concert with FILTER_VALIDATE_EMAIL to reduce user error or prevent XSS-related attacks (as some past XSS attacks involved the returning of the original data provided in a non-sanitized e-mail field directly to the browser).

FILTER_SANITIZE_URL: Similar to the e-mail address sanitize filter, this filter does exactly what one would think, as well. It removes any characters that are invalid in a URL (like certain UTF-8 characters, etc). For example, let’s say you accidentally added a “®” into your website’s URL (again, don’t ask how, pretend a velociraptor did it):


<?php

$value = 'http://w3programmers®.com';

echo filter_var($value, FILTER_SANITIZE_URL);

?>

It removes the unwanted “®” and you get your handsome URL back:

http://w3programmers.com

FILTER_SANITIZE_NUMBER_INT: This filter is similar to the FILTER_VALIDATE_INT but instead of simply checking if it is an Integer or not, it actually removes everything non-integer from the value! Handy, indeed, for pesky spambots and tricksters in some input forms:

Example: FILTER_SANITIZE_NUMBER_INT1.php


<?php

$value01 = '123abc456def';

echo filter_var($value01, FILTER_SANITIZE_NUMBER_INT);

echo '<br />';

$value02 = '1.2.3.4.5.6.7.8.9';

echo filter_var($value02, FILTER_SANITIZE_NUMBER_INT);

?>

Those silly letters and decimals get thrown right out:

123456

123456789

FILTER_SANITIZE_NUMBER_FLOAT: This filter is similar to the FILTER_VALIDATE_INT but instead of simply checking if it is an Integer or not, it actually removes everything non-integer from the value! Handy, indeed, for pesky spambots and tricksters in some input forms:

Example: FILTER_SANITIZE_NUMBER_FLOAT.php


<?php

$value01 = '123abc456def';

echo filter_var($value01, FILTER_SANITIZE_NUMBER_FLOAT);

echo '<br />';

$value02 = '1.2.3.4.5.6.7.8.9';

echo filter_var($value02, FILTER_SANITIZE_NUMBER_FLOAT);

?>

Again, all those silly letters and decimals get thrown right out:

123456
123456789

But what if you wanted to keep a decimal like in the next example:

Example: FILTER_SANITIZE_NUMBER_FLOAT1.php


<?php

$value = '1.23';

echo filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT);

?>

It would still remove it and return:

123

One of the main reasons why FILTER_SANITIZE_NUMBER_FLOAT and FILTER_SANITIZE_INT are separate filters is to allow for this via a special Flag “FILTER_FLAG_ALLOW_FRACTION” that is added as a third value passed to filter_var:

Example: FILTER_FLAG_ALLOW_FRACTION1.php


<?php

$value = '1.23';

echo filter_var($value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION);

?>

It would keep the decimal and return:

1.23

Callback Filter

The FILTER_CALLBACK filter does exactly what it says. Calls a user-defined function to filter our data. This functionality permits us full control of the filtering of data. Here we will begin with a simple user defined function that converts spaces to underscores.

</p>
<?php

&nbsp;

/**

* Callback function

* Convert spaces to underscores

*

* @param $string

*

* @return string

*

**/

function space2underscore($string) {

return str_replace(" ", "_", $string);

}

&nbsp;

$string = "This is not a love song";

&nbsp;

echo filter_var($string, FILTER_CALLBACK, array("options"=>"space2underscore"));

&nbsp;

?>
<p style="text-align: justify;">

We see the filter has used our space2underscore() function as a callback and converted the spaces in the string so that it now returns

This_is_not_a_love_song.

We could use a PHP function rather than our own as demonstrated here


<?php

/*** a string ***/
$string = "This is not a love song";

/*** use a PHP defined function as callback ***/
echo filter_var($string, FILTER_CALLBACK, array("options"=>"ucwords"));

?>

Now we see that using a simple PHP callback function is simple on our string and the return value is

This Is Not A Love Song

. If a non-existant function is used an error an error is generated as shown below.


<?php

/*** a string ***/
$string = "w3programmers.com";

/*** a callback without a declared function ***/
filter_var($string, FILTER_CALLBACK, array("options"=>"non_existant_function"));

?>

The above script will produce an error like
Warning: filter_var() [function.filter-var]: First argument is expected to be a valid callback in /www/fil.php on line 6
We have seen above the use of several functions to use as a callback. But what if we wanted to use several functions for our callback array. Lets put it to the test.


<?php

/*** a string ***/
$string = "This is not a love song";

/*** use a PHP defined function as callback ***/
echo filter_var($string, FILTER_CALLBACK, array("options"=>array("ucwords", "strtolower")));

?>

GRIM…

We see above that the use of mulitple callbacks is not permitted and will generate an error as follows:

Warning: filter_var() [function.filter-var]: First argument is expected to be a valid callback in /home/kevin/html/fil.php on line 7.

We can however, call a class method as shown below here.


<?php

/*** class method callback ***/
class my_class{

/**
* Callback method
* Convert spaces to underscores
*
* @param $string
*
* @return string
*
**/
function space2underscore($string) {
return str_replace(" ", "_", $string);
}

}/*** end of class ***/

$string = "This is not a love song";

echo filter_var($string, FILTER_CALLBACK, array("options"=>array("my_class", "space2underscore")));

?>

Moving on from the above class we can also use a call back with a thown exception like this..


<?php

/* thrown exception in the callback */
function check_num(&$num) {
if($num != 4)
{
throw new Exception("This is an exception error message");
}
}

/*** declare a number variable ***/
$num = 3;

try {
filter_var($num, FILTER_CALLBACK, array("options"=>"check_num"));
}
catch (Exception $e)
{
echo $e->getMessage();
}
?>

From the above code we see that the $num variable does not match the value in the check_num() method and so an exception is thrown. The exception is then caught as usual in the first catch block and the error messages is displayed.

Filter an Array

Up till now we have focused on validation of variables from various sources. Here we show how the filters can be used on an array of values. This is done using the filter_var_array() function. We will show here a simulated POST array that could come from a form and how to apply different filters to the various array members.

</p>
<p style="text-align: justify;"><?php

/**
* Callback function
* @format a name
* @param string $name
* @return string formated name
**/
function formatName($name){
return ucwords(strtolower($name));
}

/*** simulated POST array ***/
$_POST = array(
"name"  => "KeViN WatersoN",
"age"   => "42",
"email" => "example@w3programmers.com",
);

/*** an array of filters ***/
$filters = array(
"name" => array("filter"=>FILTER_CALLBACK, "flags"=>FILTER_FLAG_ARRAY, "options"=>"formatName"),
"age"  => array("filter"=>FILTER_VALIDATE_INT, "flags"=>FILTER_FLAG_ARRAY, "options"=>array("min_range" => 1, "max_range" => 100)),
"email"    => FILTER_VALIDATE_EMAIL,
);

/*** apply the filters to the array ***/
$filtered_array = filter_var_array($_POST, $filters);

/*** loop and display keys and values ***/
foreach($filtered_array as $k=>$v)
{
echo $k." - ".$v."<br />";
}
?></p>
<p style="text-align: justify;">

Lets step through the above code to see what we have done here. The output will be like:

name – Kevin Waterson

age – 42

email – example@w3programmers.com

We began with a simple callback function that we use to apply later in the script. Next we created a simulated POST array to simulate the data coming from a form, or possibly CURL. We then create an array of filters we wish to supply to each of the POST variables. It is then a simple matter for us to apply the filters array to the POST array with the filter_var_array() function. We loop over our filtered_array and see the values. This is by far a superior method of handling variables from users. Of course the POST data could be any array of data. You may be able to see how helpful the callback filter will be when used on POST data intended for INSERTing into a database. A simple callback to a function such as mysql_real_escape_string(), as seen previously, would make life a lot simpler for some.

As mentioned, any array could be used. A POST array was used above as an example, but there is a better way to hand inputs using the filter_input_array. Like the filter_input() function, the filter_input_array() function takes it array of values from inputs as follows

  • INPUT_GET
  • INPUT_POST
  • INPUT_COOKIE
  • INPUT_SERVER
  • INPUT_ENV
  • INPUT_SESSION
  • INPUT_REQUEST

<form method="post">
<input type="text" name="name"  value="Kevin" /><br />
<input type="text" name="age"   value="42" /><br />
<input type="text" name="email" value="example@w3programmers.com" /><br />
<input type="submit" />
</form>
<?php

$filters = array(
"age"   =>array("filter"=>FILTER_VALIDATE_INT, "flags"=>FILTER_FLAG_ARRAY|FILTER_NULL_ON_FAILURE, "options"=>array("min_range"=>0, "max_range"=>100)),
"name"  => FILTER_SANITIZE_SPECIAL_CHARS,
"email" => FILTER_SANITIZE_EMAIL,
"notset"=> FILTER_VALIDATE_INT
);

/*** apply the filters to the POST array ***/
$filtered = filter_input_array(INPUT_POST, $filters);

/*** echo the filtered array members ***/
echo $filtered['name'] .'<br />'. $filtered['age'] .'<br />'. $filtered['email'].'<br />';

/*** check for the notset variable ***/
if(filter_has_var(INPUT_POST, "notset") !== false)
{
echo 'Variable is in filter';
}
else
{
var_dump($filtered["notset"]);
}
?>

Stepping through this code we see some familiar filters and some new introductions. When using the FILTER_VALIDATE_INT for the age variable we have added the flag constant FILTER_NULL_ON_FAILURE. This flag tells the filter engine to return NULL rather than bool(false) if the filter fails. This can be handy if we wish to INSERT into a database or something. Wehave used the filter_input_array() function to apply the filters to their respective POST variables much the same as we did with the filter_var_array() function earlier. From there it is simple to echo the filtered array members, or if our program dictated, we may have other uses for them.

At the very last we have used the filter_has_var() function to check if the variable notset is in the INPUT_POST filter. As it is not it returns NULL as seen with the var_dump().

Filter an Array with CALLBACK

Of course, not all arrays come from outside our scripts. Quite often we need to perform operations on our own arrays. Previously, if we wanted to use a callback would would have used array_walk() to apply a callback function. The filter extension deals with this just as simply as with any array. In the following example we will do something useful. The task of hiding email addresses from spam bots is an age old task and many have taken to use ASCII values instead to print thier mails. Latter day spambots read these also, but it makes for a good callback example to iterate over each character of an email address and convert it to its ASCII value using the PHP ord() function.


<?php
echo encodeEmail('example@w3programmers.com');

/**
*
* Return ASCII value web use
*
* @param string
*
* @return string
*
*/
function makeASCII($char=0){
return '&#'.ord($char).';';
}

/**
*
* @Encode an email to ascii
*
* @parma string
*
* @return string
*
*/
function encodeEmail($email){
/*** check if the filter has a var ***/
if(filter_var($email, FILTER_VALIDATE_EMAIL) !== FALSE)
{
/*** split the email into single chars ***/
$charArray = str_split($email);
/*** apply a callback funcion to each array member ***/
$encodedArray = filter_var($charArray, FILTER_CALLBACK, array('options'=>"makeASCII"));
/*** put the string back together ***/
$encodedString = implode('',$encodedArray);
return '<a href="mailto:'.$encodedString.'">'.$encodedString.'</a>';
}
else
{
return false;
}
}

?>

The string resulting from this will be an ASCII encode mail address for use on a web page like this

<a href=”mailto:&#107;&#101;&#118;&#105;&#110;&#64;&#112;&#104;&#112;&#114;&#111;&#46;&#111;&#114;&#103;”>&#107;&#101;&#118;&#105;&#110;&#64;&#112;&#104;&#112;&#114;&#111;&#46;&#111;&#114;&#103;<a>

More importantly, what we have done is used the filter_var() function on an array, just as we would a string. The same principles apply and the filter will apply the callback function to each member of the array. It does’nt get any easier than this.

Other Methods of Santizing Data with PHP

Now, we’ll go over a few key supplemental methods of sanitizing data with PHP to prevent “dirty data” from wreaking havoc on your systems. These are especially useful for applications still running PHP 4, as they were all available when it was released.

Magic Quotes

The use of magic quotes in PHP has been a contentious issue from its inception. The removal of magic quotes in favour of user defined escaping of characters makes a lot of sense. Here we can impliment the functionality of magic quotes without having them force upon us by php.ini settings which may vary from server to server. The FILTER_SANITIZE_MAGIC_QUOTES filter applies the addslashes function to a string, thus providing us with an escaped string for use in our applications.


<?php

/*** a string ***/
$string = "test'test2'test3'' test\'\"test5";

/*** sanitize the float ***/
echo filter_var($string, FILTER_SANITIZE_MAGIC_QUOTES)

?>

As we can see, this above script returns

test\’test2\’test3\’\’ test\\\’\”test5

as the addslashes() function has been applied to the string and escaped the characters that need to be escaped.

htmlspecialchars: This PHP function converts 5 special characters into their corresponding HTML entities:

  • ‘&’ (ampersand) becomes ‘&amp;’
  • ‘”‘ (double quote) becomes ‘&quot;’ when ENT_NOQUOTES is not set.
  • ”’ (single quote) becomes ‘&#039;’ only when ENT_QUOTES is set.
  • ‘<’ (less than) becomes ‘&lt;’
  • ‘>’ (greater than) becomes ‘&gt;’

It is used like any other PHP string function:


<?php

echo htmlspecialchars('$string');

?>

htmlentities: Like htmlspecialchars, this PHP function converts characters into their corresponding HTML entities. The big difference is that ALL characters that can be converted will be converted. This is a useful method of obfuscating e-mail addresses from some bots that collect e-mail addresses, as not of them are programmed to read htmlentities.

It is used like any other PHP string function:


<?php

echo htmlspecialchars('$string');

?>

mysql_real_escape_string: This MySQL function helps protect against SQL injection attacks. It is considered a best practice (or even a mandatory practice) to pass all data that is being sent to a MySQL query through this function. It escapes any special characters that could be problematic and would cause little Bobby Tables to destory yet another school students database.


<?php

$query = 'SELECT * FROM table WHERE value='.mysql_real_escape_string('$string').' LIMIT 1,1';

$runQuery = mysql_query($query);

?>

Custom Functions

For many people, these built-in filters and functions are just not good enough. Data validation of some data like phone numbers, zip codes, or even e-mails often requires more strict validation and masking. To do this, many people create custom functions to validate and their data is real. An example of this may be as simple as using a MySQL query to look up the data in a database of known values like so:


<?php

function checkZipCode($value) {

$zipcheck = 'SELECT COUNT(*) FROM `database`.`zipcodes` WHERE value="'.filter_var(mysql_real_escape_string($value),FILTER_SANITIZE_NUMBER_INT).'"';

$count = mysql_query($zipcheck);

if($count==1) {

return TRUE;

} else {

return FALSE;

}

}

?>

Other custom functions can be made that do not rely on databases of known values, and can be created by checking magic-quotes, stripping slashes, and escaping for insert into a database:


function cleanString($string) {

$detagged = strip_tags($string);

if(get_magic_quotes_gpc()) {

$stripped = stripslashes($detagged);

$escaped = mysql_real_escape_string($stripped);

} else {

$escaped = mysql_real_escape_string($detagged);

}

return $escaped;

}

Example: An Email Submit Form

Now that data sanitation and validation have been covered, we’ll put those skills to use with a quick email submission form. This will by no means be of production quality — for example, no form should require a home page — but it’ll work perfect for this tutorial. The form will take 4 pieces of information:

  • Name
  • Email Address
  • Home Page
  • Message

We’ll sanitize and validate against all 4 pieces of data and only send the email if they are all valid. If anything is invalid, or if any fields are blank, the form will be presented to user along with a list of items to fix. We’ll also return the sanitized data to the user in case they are unaware that certain characters are illegal.

Step 1 – Creating the Form

For the first step, simply create a form element with 5 fields: the for listed above and a submit button:


<form name="form1" method="post" action="form-email.php">

Name: <br/>

<input type="text" name="name" value="<?php echo $_POST['name']; ?>" size="50" /><br/><br/>

Email Address: <br/>

<input type="text" name="email" value="<?php echo $_POST['email']; ?>" size="50"/> <br/><br/>

Home Page: <br/>

<input type="text" name="homepage" value="<?php echo $_POST['homepage']; ?>" size="50" /> <br/><br/>

Message: <br/>

<textarea name="message" rows="5" cols="50"><?php echo $_POST['message']; ?></textarea>

<br/>

<input type="submit" name="Submit" />

</form>

Step 2 – Determine if the Form was Submitted

You can check to see if a form was submitted by seeing if the submit button was “set”. Place the following code above your form:


if (isset($_POST['Submit'])) {

}

Step 3 – Validating the Name and Message Field

Since both the name and message fields will be sanitized and validated the same, we’ll do them together. First, check to see if either field is blank by doing the following:


if ($_POST['name'] == "")

if ($_POST['message'] == "")

Next, sanitize them with the FILTER_SANITIZE_STRING constant


$_POST['name'] = filter_var($_POST['name'], FILTER_SANITIZE_STRING);

$_POST['message'] = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

Finally, check to make sure that the two fields still are not blank. This is to ensure that after removing all illegal characters, you are not left with a blank field:


if ($_POST['name'] == "")

if ($_POST['message'] == "")

We won’t do any validation on these two fields simply because there is no absolute way to validate against a Name or arbitrary message.

The final code looks like this:


if ($_POST['name'] != "") {

$_POST['name'] = filter_var($_POST['name'], FILTER_SANITIZE_STRING);

if ($_POST['name'] == "") {

$errors .= 'Please enter a valid name.<br/><br/>';

}

} else {

$errors .= 'Please enter your name.<br/>';

}

if ($_POST['message'] != "") {

$_POST['message'] = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

if ($_POST['message'] == "") {

$errors .= 'Please enter a message to send.<br/>';

}

} else {

$errors .= 'Please enter a message to send.<br/>';

}

Step 4 — Validate the Email Field

The email field will be sanitized and validated just as it was earlier in the tutorial.

First, check to make sure it is not blank:


if ($_POST['email'] != "")

Next, sanitize it:


$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

Finally, validate it as a true email address:


if (!filter_var($email, FILTER_VALIDATE_EMAIL))

The final code looks like this:


if ($_POST['email'] != "") {

$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

$errors .= "$email is <strong>NOT</strong> a valid email address.<br/><br/>";

}

} else {

$errors .= 'Please enter your email address.<br/>';

}

Step 5 — Validate the Home Page Field

Again, the home page field will be sanitized and validated the same way as earlier in the tutorial.

First, make sure it is not blank:


if ($_POST['homepage'] != "")

Next, sanitize it and remove any illegal characters:


$homepage = filter_var($_POST['homepage'], FILTER_SANITIZE_URL)

Finally, validate it to make sure it’s a true URL:


if (!filter_var($homepage, FILTER_VALIDATE_URL))

The final code looks like this:


if ($_POST['homepage'] != "") {

$homepage = filter_var($_POST['homepage'], FILTER_SANITIZE_URL);

if (!filter_var($homepage, FILTER_VALIDATE_URL)) {

$errors .= "$homepage is <strong>NOT</strong> a valid URL.<br/><br/>";

}

} else {

$errors .= 'Please enter your home page.<br/>';

}

Step 6 — Check for Errors and Send the Message

Now that we’ve gone through all fields, it’s time to either report the errors or send the message. Start off by assuming there were no errors:


if (!$errors) {

Then build the email message:


$mail_to = 'me@somewhere.com';

$subject = 'New Mail from Form Submission';

$message  = 'From: ' . $_POST['name'] . "\n";

$message .= 'Email: ' . $_POST['email'] . "\n";

$message .= 'Homepage: ' . $_POST['homepage'] . "\n";

$message .= "Message:\n" . $_POST['message'] . "\n\n";

And finally, send the message:


mail($to, $subject, $message);

However, if there were any errors, report them and have the user try again:


echo '<div style="color: red">' . $errors . '<br/></div>';

The completed project looks like this:


<?php

if (isset($_POST['Submit'])) {

if ($_POST['name'] != "") {

$_POST['name'] = filter_var($_POST['name'], FILTER_SANITIZE_STRING);

if ($_POST['name'] == "") {

$errors .= 'Please enter a valid name.<br/><br/>';

}

} else {

$errors .= 'Please enter your name.<br/>';

}

if ($_POST['email'] != "") {

$email = filter_var($_POST['email'], FILTER_SANITIZE_EMAIL);

if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {

$errors .= "$email is <strong>NOT</strong> a valid email address.<br/><br/>";

}

} else {

$errors .= 'Please enter your email address.<br/>';

}

if ($_POST['homepage'] != "") {

$homepage = filter_var($_POST['homepage'], FILTER_SANITIZE_URL);

if (!filter_var($homepage, FILTER_VALIDATE_URL)) {

$errors .= "$homepage is <strong>NOT</strong> a valid URL.<br/><br/>";

}

} else {

$errors .= 'Please enter your home page.<br/>';

}

if ($_POST['message'] != "") {

$_POST['message'] = filter_var($_POST['message'], FILTER_SANITIZE_STRING);

if ($_POST['message'] == "") {

$errors .= 'Please enter a message to send.<br/>';

}

} else {

$errors .= 'Please enter a message to send.<br/>';

}

if (!$errors) {

$mail_to = 'me@somewhere.com';

$subject = 'New Mail from Form Submission';

$message  = 'From: ' . $_POST['name'] . "\n";

$message .= 'Email: ' . $_POST['email'] . "\n";

$message .= 'Homepage: ' . $_POST['homepage'] . "\n";

$message .= "Message:\n" . $_POST['message'] . "\n\n";

mail($to, $subject, $message);

echo "Thank you for your email!<br/><br/>";

} else {

echo '<div style="color: red">' . $errors . '<br/></div>';

}

}

?>

<form name="form1" method="post" action="form-email.php">

Name: <br/>

<input type="text" name="name" value="<?php echo $_POST['name']; ?>" size="50" /><br/><br/>

Email Address: <br/>

<input type="text" name="email" value="<?php echo $_POST['email']; ?>" size="50"/> <br/><br/>

Home Page: <br/>

<input type="text" name="homepage" value="<?php echo $_POST['homepage']; ?>" size="50" /> <br/><br/>

Message: <br/>

<textarea name="message" rows="5" cols="50"><?php echo $_POST['message']; ?></textarea>

<br/>

<input type="submit" name="Submit" />

</form>

Output:

Sanitize and Validation Example

Hi, My name is Masud Alam, love to work with Open Source Technologies, living in Dhaka, Bangladesh. I graduated in 2009 with a bachelor’s degree in Engineering from State University Of Bangladesh, I’m also a Certified Engineer on ZEND PHP 5.3, I served my first five years a number of leadership positions at Winux Soft Ltd, SSL Wireless Ltd, CIDA and MAX Group where I worked on ERP software and web development., but now i’m a co-founder and Chief Executive Officer and Managing Director of TechBeeo Software Consultancy Services Ltd. I’m also a Course Instructor of ZCPE PHP 7 Certification and professional web development course at w3programmers Training Institute – a leading Training Institute in the country.

2 comments on “Sanitize and Validate Data with PHP Filters
  1. Attention in the FILTER_VALIDATE_BOOLEAN sample there’s an error in what you say.
    If you run the script you’ll see that
    $value1 and $value2 are both TRUE

Leave a Reply

Your email address will not be published. Required fields are marked *