Menu

PHP filter_var(): Validate Email, Int, URL and More

filter_var($value, FILTER_VALIDATE_EMAIL) returns the value if it is valid and false if not; FILTER_VALIDATE_INT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL and FILTER_VALIDATE_IP work the same way. Learn the options (min_range, default), flags, sanitize filters and the false vs 0 trap.

This page includes runnable editors - edit, run, and see output instantly.

filter_var($value, FILTER_VALIDATE_EMAIL) returns the value when it is a valid email address and false when it is not. Swap the filter to check other formats: FILTER_VALIDATE_INT, FILTER_VALIDATE_FLOAT, FILTER_VALIDATE_URL, FILTER_VALIDATE_BOOL, FILTER_VALIDATE_IP. Always compare the result with === false.

Two results surprise people. ada@example is rejected because the domain has no dot, and ' ada@example.com' is rejected because of the leading space, so trim() input before you validate it.

Validate an email from a form

The same check behind a form. Run it, type an address and press Check; the block runs again with your input in $_POST.

FILTER_VALIDATE_EMAIL checks the format only. nobody@example.com passes, and so would an address with a typo in the domain. Non-ASCII characters are rejected: adä@example.com passes only with FILTER_FLAG_EMAIL_UNICODE, which allows them before the @, and a domain like exämple.com fails even with the flag unless you convert it to its xn-- form first. The only way to know an address works is to send it a confirmation link.

Validate an integer, with min_range and max_range

FILTER_VALIDATE_INT turns a valid string into an int and rejects everything else. The options array adds a range and a default:

Surrounding whitespace and a leading + are accepted, a leading zero ('042') is not, and the result for '42' is the integer 42, not the string. Out of range gives false; with a default option you get the default instead of false, which is handy for things like ?page= (see GETand_GET and _POST). Add FILTER_FLAG_ALLOW_HEX or FILTER_FLAG_ALLOW_OCTAL to accept 0x1A or 0755.

The 0 and false trap

A valid '0' returns the integer 0, and 0 is falsy. A plain if treats it as a failure:

The same applies to FILTER_VALIDATE_FLOAT ('0.0') and FILTER_VALIDATE_BOOL, where false is a valid answer. That is what FILTER_NULL_ON_FAILURE is for.

Booleans, floats, URLs and IP addresses

FILTER_VALIDATE_BOOL is the PHP 8 name; FILTER_VALIDATE_BOOLEAN is the same filter. Without FILTER_NULL_ON_FAILURE, 'maybe' would return false, indistinguishable from 'off'.

FILTER_VALIDATE_URL checks that the string is shaped like a URL, with any scheme. That includes schemes you never want in an href:

javascript://comment%0Aalert(1) passes FILTER_VALIDATE_URL, and a browser runs it as JavaScript when the link is clicked, because %0A ends the //comment. Check the scheme with parse_url() before you print a user's URL into a page. You can also require parts with FILTER_FLAG_PATH_REQUIRED and FILTER_FLAG_QUERY_REQUIRED.

Sanitize filters

Sanitize filters remove characters instead of saying yes or no. They are useful for normalizing input, not for making it safe to print:

Look at the first line: Order #12-345 (x2) becomes 12-3452, a number that was never in the input, and the third line is an address nobody typed. If you sanitize, validate the result afterwards. For anything you print into HTML, htmlspecialchars() at output time is the right tool (FILTER_SANITIZE_FULL_SPECIAL_CHARS does the same escaping). FILTER_SANITIZE_STRING is deprecated since PHP 8.1; see htmlspecialchars for what to use instead.

Validate a whole form with filter_var_array

filter_var_array() applies one filter per key and returns an array with every key you asked for: the filtered value, false when validation failed, or null when the key was missing.

role is gone: keys you did not list are dropped, which stops a visitor from adding role=admin to a form and having it saved. country is null because it was not sent. On a web server, filter_input_array(INPUT_POST, $rules) does the same thing reading straight from the request.

Frequently Asked Questions

How do I validate an email address in PHP?

Use filter_var($email, FILTER_VALIDATE_EMAIL), which returns the email string if it is valid and false if not: if (filter_var($email, FILTER_VALIDATE_EMAIL) === false) { /* invalid */ }. It checks the format only; to know the address exists, send a confirmation email.

How do I check if a string is an integer in PHP?

filter_var($s, FILTER_VALIDATE_INT) returns the int for "42", "-7" and " 42 ", and false for "4.2", "42abc" or "042". Compare with !== false, because a valid "0" returns 0, which is falsy.

Why does filter_var return false for 0?

It does not: filter_var('0', FILTER_VALIDATE_INT) returns the integer 0. The bug is in the check, if (filter_var(...)), which treats 0 like false. Write if (filter_var($v, FILTER_VALIDATE_INT) !== false).

What replaced FILTER_SANITIZE_STRING in PHP 8.1?

Nothing directly; it was deprecated because its name promised safety it did not give. Validate the input you expect, store it as is, and escape it when you print it with htmlspecialchars(). If you need tags removed, use strip_tags().

What is the difference between filter_var and filter_input?

filter_var() filters any value you pass. filter_input(INPUT_GET, 'id', FILTER_VALIDATE_INT) reads straight from the original request, so it returns null when the parameter is missing and ignores any changes your code made to $_GET. Both take the same filters and options.

Coddy programming languages illustration

Learn to code with Coddy

GET STARTED