filter_var
Validates or sanitizes a single value with a built-in filter, returning false when it fails.
filter_var(mixed $value, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed- Added in PHP 5.2.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$value | mixed | The value to filter. Scalar values are converted to string internally before filtering. |
$filteroptional | int= FILTER_DEFAULT | The filter to apply: a FILTER_VALIDATE_*, FILTER_SANITIZE_*, FILTER_UNSAFE_RAW or FILTER_CALLBACK constant. |
$optionsoptional | array|int= 0 | An associative array with 'flags' and 'options' keys, or a bitmask of FILTER_FLAG_* constants. |
Return value
mixedThe filtered value on success, or false on failure. With the FILTER_NULL_ON_FAILURE flag, null is returned on failure instead.
Errors
Throws a ValueError when incompatible flags are combined — for example "filter_var(): Argument #3 ($options) cannot use both FILTER_NULL_ON_FAILURE and FILTER_THROW_ON_FAILURE". An unknown filter ID does not throw: filter_var('x', 99999) raises an "Unknown filter with ID 99999" warning and returns false. In PHP 8.5, a validation failure throws Filter\FilterFailedException if FILTER_THROW_ON_FAILURE is set.
Changelog
- PHP 8.5The FILTER_THROW_ON_FAILURE flag was added; a failing validation filter throws Filter\FilterFailedException instead of returning false. Combining it with FILTER_NULL_ON_FAILURE throws a ValueError.
- PHP 8.1FILTER_SANITIZE_STRING and its alias FILTER_SANITIZE_STRIPPED are deprecated; use htmlspecialchars() instead.
- PHP 8.0FILTER_VALIDATE_BOOL was introduced as the canonical name for FILTER_VALIDATE_BOOLEAN, and the always-implied FILTER_FLAG_SCHEME_REQUIRED and FILTER_FLAG_HOST_REQUIRED flags were removed.
filter_var() is the workhorse of the filter extension. Hand it a value and a filter constant and it either gives you back a clean, correctly typed result or tells you the value is unacceptable.
There are two families. Validation filters (FILTER_VALIDATE_INT, _FLOAT, _BOOL, _EMAIL, _URL, _IP, _MAC, _DOMAIN, _REGEXP) check the value and return it converted to the right PHP type — '42' comes back as int(42), not a string. Sanitization filters (FILTER_SANITIZE_*) never fail; they strip or encode characters and hand back a string.
When to reach for it
Use validation filters at the boundary of your app, where a string from a form, a CLI argument or a JSON body has to become a typed value you can trust. FILTER_VALIDATE_INT with min_range and max_range replaces a pile of is_numeric() and comparison code in one call.
What trips people up
The false return is ambiguous whenever false or 0 is itself a legal result. FILTER_VALIDATE_BOOL is the classic trap. Add FILTER_NULL_ON_FAILURE, or in PHP 8.5 FILTER_THROW_ON_FAILURE, so failure has its own unmistakable signal.
Remember too that validation filters check syntax: a syntactically valid email may not be deliverable, and a valid URL may point anywhere.
Example
When to use it
- Turn a query-string page number into a real int constrained to 1..500 in one call.
- Check a signup email address before sending a confirmation message.
- Confirm a user-supplied string is a routable public IPv4 address before making a request to it.
- Encode user text for safe insertion into HTML with FILTER_SANITIZE_FULL_SPECIAL_CHARS.
Frequently asked questions
How do I validate an email address in PHP?
Use filter_var($email, FILTER_VALIDATE_EMAIL), which returns the address on success and false on failure. It checks the syntax only, so send a confirmation message if you need to know the mailbox actually exists.
What is the difference between FILTER_VALIDATE_INT and is_numeric?
is_numeric() accepts floats, exponents and surrounding whitespace and returns only a boolean — it rejects hexadecimal strings such as "0x1A", which have not been numeric since PHP 7.0. FILTER_VALIDATE_INT accepts whole numbers only, supports min_range and max_range, and returns the value already converted to an int.
Why does filter_var return false for a valid value?
Because false is also the failure signal, and FILTER_VALIDATE_BOOL legitimately returns false for inputs like "no" or "0". Add the FILTER_NULL_ON_FAILURE flag so failure returns null, or on PHP 8.5 use FILTER_THROW_ON_FAILURE.
More examples
Ranges, defaults and unambiguous failure
The out-of-range 500 and the nonsense "maybe" both come back as <code>NULL</code>, while the legitimately false value <code>'0'</code> stays <code>bool(false)</code>. Without FILTER_NULL_ON_FAILURE the last two lines would both print <code>bool(false)</code> and be indistinguishable.
<?php
$opts = [
'options' => ['min_range' => 1, 'max_range' => 100],
'flags' => FILTER_NULL_ON_FAILURE,
];
var_dump(filter_var('50', FILTER_VALIDATE_INT, $opts)); // int(50)
var_dump(filter_var('500', FILTER_VALIDATE_INT, $opts)); // NULL
var_dump(filter_var('0', FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE)); // bool(false)
var_dump(filter_var('maybe', FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE)); // NULLThrowing on failure (PHP 8.5)
The out-of-range port throws <code>Filter\FilterFailedException</code> (a subclass of <code>Filter\FilterException</code>, itself an <code>Exception</code>) instead of returning false, so a forgotten check can no longer let bad data through. The valid 8080 still returns <code>int(8080)</code>. Available from PHP 8.5; it cannot be combined with FILTER_NULL_ON_FAILURE.
<?php
try {
filter_var('99999', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 1, 'max_range' => 65535],
'flags' => FILTER_THROW_ON_FAILURE,
]);
} catch (Filter\FilterFailedException $e) {
echo 'rejected: ', $e->getMessage(), "\n";
}
var_dump(filter_var('8080', FILTER_VALIDATE_INT, ['flags' => FILTER_THROW_ON_FAILURE]));IP and URL validation with flags
The private 192.168.1.1 is rejected by FILTER_FLAG_NO_PRIV_RANGE, which is the check you want before letting user input drive an outbound request. The last two lines show why FILTER_VALIDATE_URL is not enough on its own: it only checks syntax, so you still have to inspect the scheme yourself.
<?php
$flags = ['flags' => FILTER_FLAG_IPV4 | FILTER_FLAG_NO_PRIV_RANGE];
var_dump(filter_var('8.8.8.8', FILTER_VALIDATE_IP, $flags)); // string
var_dump(filter_var('192.168.1.1', FILTER_VALIDATE_IP, $flags)); // bool(false)
$url = 'https://example.com/path?a=1';
var_dump(filter_var($url, FILTER_VALIDATE_URL) !== false);
var_dump(parse_url($url, PHP_URL_SCHEME));
Discussion