PHP Validation with Filter_Var

Validating user inputs from forms and web pages has been needed to protect web sites and their databases from malfeasance.  Essentially, you don't want users to make a mistake, and put the wrong information in the database, or worse, have a hacker try to wipe out your database with a form entry.

There have been many methods of validating user input in both JavaScript and PHP in the past that were time consuming, one of which was to write regular expressions for each type of input to check, for example, that the input was a correct email, or url, or any other data entry value.  Since writing regular expression values takes a lot of effort to get an inclusive statement, the PHP folks decided to help us all, and fix this problem in PHP 5.2 and onward.  They created a PHP filter function.

But first a slight digression.  PHP separates filtering into two areas: validation and sanitizing.  Validation means to check entries for the correct specified data type and syntax.  Sanitizing means taking out unwanted characters from an entry, it will remove them from the data.  It does not do validation, which you could do before or after sanitizing.

Between you and me,  I would rather send the bad entry back to the user, and tell him, or her, to correct it, rather than take the offending character out.  The user learns what is acceptable by correcting his entry, and hopefully, learns something in the process.  Of course, that means the user has to find the error in his input.  This, also, means your validation code better be pretty inclusive to catch every possible error or attempt to subvert the application.  For this article, I'm just going to deal with validation, even though validation and sanitizing are not mutually exclusive.  And sometimes a valid variable might need to be sanitized.  We'll cover that in another article.

Let's take a look at how validation works using the filer_var() method.  The filter_var method was included in the main code of PHP5.2.  So, filter_var() is always available for use in your code, and it's not necessary to turn it on, as you would with an extension. Here's the syntax:

filter_var( <what your filtering>, <the type of filter>, <filter options and flags> )

This is very simple to use.  Let's look at an example.

We'll check an email address, first a correct email and then an obvious wrong email

$goodemail = "agood@email.com";
$bademail = "a.bad@email@another@emai.com";

Let's validate the two with this call:

$thegood = filter_var($goodemail, FILTER_VALIDATE_EMAIL);
$thebad = filter_var($bademail, FILTER_VALIDATE_EMAIL);

Here's the output:

filteremail2-620If your email data input from the user is good, the input is moved to the new variable for use in the application.  If your validation does not check out, you'll get a Boolean false, or 0, that you can test for, and then send the input back to the user for correction. Pretty simple.

Let's do another check to demonstrate the use of the optional <filter options or flags>

$goodfloat = 1.314567;
$badfloat = "1,234,556.01";

$thegood = filter_var($goodfloat, FILTER_VALIDATE_FLOAT);
$thebad = filter_var($badfloat, FILTER_VALIDATE_FLOAT);

But we want the thousand commas to be ok for user input, so let's add a flag

$badfloat = "1,234,556.01";
$nowgoodfloat = filter_var($badfloat, FILTER_VALIDATE_FLOAT, FILTER_FLAG_ALLOW_THOUSAND);

And let's take a look at our results:

filterlfoat620Some points from the three tests.  The good test had no problem and came back as expected.

In the bad test, in order for PHP not to throw a syntax error on the $badfloat assignment, we had to make $badfloat a string by putting quotes around it.  Our variable checker picked up that $badfloat was a string and not a float.  The string did not affect the float filter_var test itself.  The $thebad result came back with a Boolean false, because of the commas in the float.

On the other hand, what if we were OK with the commas, and didn't want the test to fail, because of commas in the float value.  If we set a flag in the float test in the third example, even though we again used the same $badfloat string that failed in the previous test, the test came back as valid, took the commas out of the variable, and turned the string into a float for further processing.

Sometimes you want to limit your validation to a certain number of values, or you still may want to include a regular expression.  To handle this some of the filter types allow for options that are put into an array, let's take a look.

We'll use an INT this time.

$theint = 12345;
$int_one = filter_var($theint, FILTER_VALIDATE_INT);

    $options = array(
        'options' => array(
            'default' => NOTINRANGE,
            'min_range' => 0,
            'max_range' => 123
        ),
        'flags' => FILTER_FLAG_ALLOW_OCTAL,
    );

$int_two = filter_var( $theint, FILTER_VALIDATE_INT, $options);

Let's adjust the max_range option so our INT now is in range.

$theint = 12345;

    $options = array(
        'options' => array(
            'default' => NOTINRANGE,
            'min_range' => 0,
            'max_range' => 123456
        ),
        'flags' => FILTER_FLAG_ALLOW_HEX,
    );


$int_three = filter_var( $theint, FILTER_VALIDATE_INT, $options);

Which gives us:

filterint2-620The INT test gives us three option.  Default says if it's an INT, and out of range, use the default.  The default can be a number or a string, since you can set the default to anything, you can easily use it to test your INT, and do something if it doesn't pass the test.

VALIDATION FILTERS

What validation types, other filters, and flags are available for validation with filter_var()?

FILTER_VALIDATE_BOOLEAN
TRUE is returned for "1", "true", "on" and "yes",
FALSE is returned for "0", "false", "off", "no", and "".
Options:
DEFAULT  set a value of your choice on failure
Flags:
FILTER_NULL_ON_FAILURE  FALSE is returned for "0", "false", "off", "no", and "".
Null is returned for all non-Boolean values

FILTER_VALIDATE_EMAIL
Valid emails return the valid email.  Bad emails are returned as a Boolean FALSE
Options:
DEFAULT  set a value of your choice on failure
No Flags

FILTER_VALIDATE_FLOAT
Valid returns the valid float.  Bad floats come back as Boolean FALSE
Options:
DEFAULT  set a value of your choice on failure
DECIMAL  Allow decimal
Flags:
FILTER_FLAG_ALLOW_THOUSAND   Allows a comma (,) as a thousands separator in numbers.

FILTER_VALIDATE_INT
Valid returns the INT.  A bad INT come back as Boolean FALSE
Options:
DEFAULT  set a value of your choice on failure
MIN_RANGE  The minimum INT allowed
MAX_RANGE  The maximum INT allowed
Flags:
FILTER_FLAG_ALLOW_OCTAL   Regards inputs starting with a zero (0) as octal numbers.
This only allows the succeeding digits to be 0-7.

FILTER_FLAG_ALLOW_HEX     Regards inputs starting with 0x or 0X as hexadecimal numbers.
This only allows succeeding characters to be a-fA-F0-9.

As of PHP5.4.11, the numbers +0 and -0 come up as valid for both Floats and INTs. Before PHP5.4.11 they only came up valid as Floats.

FILTER_VALIDATE_IP
Valid returns the IP address.
Options:
DEFAULT  set a value of your choice on failure
Flags:
FILTER_FLAG_IPV4                Allows the IP address to be in the IPv4 format
FILTER_FLAG_IPV6                Allows the IP address to be in the IPv6 format

FILTER_FLAG_NO_PRIV_RANGE       Fails validation for the following private IPv4 ranges: 10.0.0.0/8, 172.16.0.0/12 and 192.168.0.0/16.
Fails validation for the IPv6 addresses starting with FD or FC.

FILTER_FLAG_NO_RES_RANGE        Fails validation for the following reserved IPv4 ranges: 0.0.0.0/8, 169.254.0.0/16, 192.0.2.0/24 and 224.0.0.0/4.
This flag does not apply to IPv6 addresses.

FILTER_VALIDATE_REGEXP
Options:
DEFAULT  set a value of your choice on failure
REGEXP   Validates against a Perl_compatible regular expression
No Flags

FILTER_VALIDATE_URL
Options:
DEFAULT  set a value of your choice on failure
Flags:
FILTER_FLAG_PATH_REQUIRED   Requires the URL to contain a path part
FILTER_FLAG_QUERY_REQUIRED  Requires the URL to contain a query string

This one requires you to do a little pre_validation checking.  Your URL should not contain http://, or https://, ssh://, or mailto:.
It will only find ASCII URL's to be valid, any international characters will come up false.

The filter_var method is quick and easy to use validation method for your user inputs.  Occasionally, you may run into a valid variable, IP, or email that is just not getting past the filter_var method.  In those special cases, there still may be a need to use a regular expression for validation, and for that PHP has a rich set of methods to handle just that, see my posts on regular expressions.  If you would like to see your variables as shown in this article, download and use my free PHP variable checker in the left sidebar menu.

Comments are closed.