Did you know that there are a whole set of nifty filtering methods built into PHP? I know it’s crazy to think that the Swiss Army Knife language of the internet would have it’s own built-in filtering system but it does. For instance a common use case would be to sanitize user input prior to using it.
What I mean is perhaps you require a user to enter an email address into a form but let’s face it there are a lot of nefarious types out there who do not wish to play by the rules so they might try entering some arbitrary text or worse attempt to escape a command prompt in the package. Obviously no body wants to hand over their hard working website to some sort of script kiddie so what do you do? You filter the input of course. We’ve all seen code with a function like the following;
// Formatted for easier viewing function valid_email_address( $email ) { $pattern = "/^[^0-9][A-z0-9_]+([.][A-z0-9_]+)*[@]"; $pattern .= "[A-z0-9_]+([.][A-z0-9_]+)*[.][A-z]{2,4}$/"; if (eregi($pattern, $email)){ return( true ); } return( false ); }
Let’s face the there are all kinds of regex recipes out there and as powerful as they are you do give up some readability in your code. Of course there is also the argument that using regex can actually hurt performance so you should use this as you method of last resort. Thankfully that’s where filter_var steps in.
function valid_email_address( $email ) { return( filter_var($email, FILTER_VALIDATE_EMAIL) ); }
I know what you are thinking and it look’s way too magickal but I assure you that it’s not. This is actually the recommended way to handle this since PHP 5.2 which is really cool. If like me you are running 5.5 then you know that this method has been in the core for a while and is very stable.
The method will examine the contents of the target variable and if it passes the filter type test, in this case FILTER_VALIDATE_EMAIL then it returns the filtered data. Another option would be to use FILTER_SANITIZE_EMAIL to actually cleanup the user input so that you can store it in a new variable for use. If all of this filtering fails then the method returns false. This will allow you to write something simple like;
if( valid_email_address( $email )) { mail($email, $my_subject, $my_message); } else { return( false ); }
But wait there’s more!
Just when you thought this couldn’t get any better there is also a filter_input method that you can use to grab the $_GET, $_POST, $_COOKIE, $_SERVER and $_ENV super globals for processing. I will tell you from my own personal experience that your mileage will vary if you intend on using the latter two in your code and there is a sort of work around that I’ll cover later in the article.
function valid_email_address( $email ) { return( filter_input(INPUT_GET, 'EMAIL', FILTER_SANITIZE_EMAIL) ); }
This construct is very handy for processing user form data. If you wanted to use $_POST then you’d simply change the input type to INPUT_POST and Bob’s your uncle. If you had a complex form that you wanted to process all of the data in a single shot you could use the more advanced filter_input_array method in lieu of this simple form. In order to use the array method you will also need to construct a definition array that informs the method of which filters to apply to specific fields in the post super global array.
Also bear in mind that there are a whole host of predefined filter validators and sanitizers available as well as additional options. Validation filters that have optional items may also include a default value which is very handy because the filter will return that value if the items fails the check. In some cases it can save you from building complex conditional ladders.
One problem I ran into is that the filter_input types of INPUT_ENV and INPUT_SERVER were not very reliable. In order to work around this deficit I resorted to the getenv() method. While is may not be as elegant it worked in my situation. During my command line experimentation, I ended up with something along the following lines:
$my_email = filter_var(getenv('EMAIL'),FILTER_VALIDATE_EMAIL); if ( ! is_null($my_email)) { print('The email address is: ' . $my_email . PHP_EOL); }
While I have not personally performed any benchmarking on these method I do believe the hype that the compiled in C routines are faster than what I could produce using the older POSIX regex and PCRE functions. In either case it is nice to have another option to work with.
Leave a Reply