PHP Filter
Learn PHP's filter extension: validate vs. sanitize, filter_var(), filter_input(), key FILTER_VALIDATE_* and FILTER_SANITIZE_* constants, and flags.
The PHP filter extension is the built-in tool for checking and cleaning data that comes from outside your script — form fields, query strings, cookies, and HTTP headers. Because that data is controlled by the user (and sometimes an attacker), you should never trust it directly. This page explains the difference between validating and sanitizing, the main functions (filter_var() and filter_input()), the filter constants you'll use most, and the gotchas that trip people up.
Validate vs. sanitize
The filter extension does two distinct jobs, and mixing them up is the most common mistake:
- Validate — checks whether a value matches a rule and returns the value if it does, or
falseif it does not. It never changes the value. UseFILTER_VALIDATE_*filters. - Sanitize — removes or escapes illegal characters and returns the cleaned string. It never tells you whether the input was "correct." Use
FILTER_SANITIZE_*filters.
Rule of thumb: validate to decide whether to accept the input, sanitize to make it safe to use. They are not interchangeable — a sanitized email is not a guarantee that the email is well-formed.
filter_var() — filter a single variable
filter_var() is the workhorse. It takes a value, a filter constant, and optional options:
filter_var(mixed $value, int $filter = FILTER_DEFAULT, array|int $options = 0): mixedValidating
<?php
$email = "[email protected]";
if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
echo "Email is valid\n";
} else {
echo "Email is invalid\n";
}
// Numbers, URLs and IPs work the same way:
var_dump(filter_var("42", FILTER_VALIDATE_INT)); // int(42)
var_dump(filter_var("not-a-number", FILTER_VALIDATE_INT)); // bool(false)
var_dump(filter_var("https://w3docs.com", FILTER_VALIDATE_URL)); // stringOutput:
Email is valid
int(42)
bool(false)
string(18) "https://w3docs.com"Gotcha: validate filters return
falseon failure, but0and""are also falsy.filter_var("0", FILTER_VALIDATE_INT)returnsint(0), which fails a naiveif. Compare with=== false, or passFILTER_NULL_ON_FAILUREso failures becomenulland you can use!== null.
Sanitizing
<?php
$dirty = " john (doe)@exa<>mple.com ";
echo filter_var($dirty, FILTER_SANITIZE_EMAIL), "\n"; // [email protected]
$comment = "<script>alert(1)</script>Hi";
echo filter_var($comment, FILTER_SANITIZE_SPECIAL_CHARS), "\n";Output:
[email protected]
<script>alert(1)</script>HiPassing options and flags
Many filters accept extra options. For example, validate an integer only inside a range:
<?php
$options = [
"options" => ["min_range" => 1, "max_range" => 120],
];
var_dump(filter_var("130", FILTER_VALIDATE_INT, $options)); // bool(false)
var_dump(filter_var("25", FILTER_VALIDATE_INT, $options)); // int(25)Output:
bool(false)
int(25)Useful flags include FILTER_NULL_ON_FAILURE (return null instead of false), FILTER_FLAG_STRIP_LOW (strip characters below ASCII 32), and FILTER_FLAG_IPV6 / FILTER_FLAG_IPV4 for narrowing FILTER_VALIDATE_IP.
filter_input() — filter request data directly
filter_input() reads a value straight from a superglobal (by name) and filters it in one step, so you never touch the raw $_POST / $_GET array:
filter_input(int $type, string $var_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixedThe $type is one of INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER, or INPUT_ENV:
<?php
// In a real form handler:
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
echo "Please enter a valid email.";
} elseif ($email === null) {
echo "The email field was not submitted.";
} else {
echo "Got: $email";
}Note the three outcomes: a value (passed), false (present but invalid), or null (the field did not exist). To filter a whole form at once, see filter_var_array() and filter_input_array().
Common filter constants
| Filter | Type | Purpose |
|---|---|---|
FILTER_VALIDATE_EMAIL | validate | Email address |
FILTER_VALIDATE_URL | validate | URL |
FILTER_VALIDATE_INT / FILTER_VALIDATE_FLOAT | validate | Whole / decimal numbers |
FILTER_VALIDATE_IP | validate | IPv4 / IPv6 address |
FILTER_VALIDATE_BOOLEAN | validate | "yes", "on", "1" → true |
FILTER_SANITIZE_EMAIL | sanitize | Strip illegal email characters |
FILTER_SANITIZE_URL | sanitize | Strip illegal URL characters |
FILTER_SANITIZE_NUMBER_INT | sanitize | Keep digits and + - |
FILTER_SANITIZE_SPECIAL_CHARS | sanitize | HTML-encode < > & " ' |
Deprecated since PHP 8.1:
FILTER_SANITIZE_STRING(and its aliasFILTER_SANITIZE_STRIPPED). For escaping output usehtmlspecialchars(); for cleaning input prefer a specific validate filter plus context-appropriate escaping at the point of use.
When should I use it?
- Checking a registration or contact form before saving — pair this with PHP Form Validation and validating URL & e-mail fields.
- Confirming a query-string
idis a positive integer before a database lookup. - Reading and trusting values from cookies or
$_SERVER.
Filtering complements, but does not replace, other defenses: use prepared statements (PHP MySQLi prepared statements) against SQL injection and htmlspecialchars() when echoing user data into HTML. For pattern-based rules the filter extension can't express, reach for regular expressions.