W3docs

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:

  • Validatechecks whether a value matches a rule and returns the value if it does, or false if it does not. It never changes the value. Use FILTER_VALIDATE_* filters.
  • Sanitizeremoves 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): mixed

Validating

<?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)); // string

Output:

Email is valid
int(42)
bool(false)
string(18) "https://w3docs.com"

Gotcha: validate filters return false on failure, but 0 and "" are also falsy. filter_var("0", FILTER_VALIDATE_INT) returns int(0), which fails a naive if. Compare with === false, or pass FILTER_NULL_ON_FAILURE so failures become null and 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]
&#60;script&#62;alert(1)&#60;/script&#62;Hi

Passing 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): mixed

The $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

FilterTypePurpose
FILTER_VALIDATE_EMAILvalidateEmail address
FILTER_VALIDATE_URLvalidateURL
FILTER_VALIDATE_INT / FILTER_VALIDATE_FLOATvalidateWhole / decimal numbers
FILTER_VALIDATE_IPvalidateIPv4 / IPv6 address
FILTER_VALIDATE_BOOLEANvalidate"yes", "on", "1"true
FILTER_SANITIZE_EMAILsanitizeStrip illegal email characters
FILTER_SANITIZE_URLsanitizeStrip illegal URL characters
FILTER_SANITIZE_NUMBER_INTsanitizeKeep digits and + -
FILTER_SANITIZE_SPECIAL_CHARSsanitizeHTML-encode < > & " '

Deprecated since PHP 8.1: FILTER_SANITIZE_STRING (and its alias FILTER_SANITIZE_STRIPPED). For escaping output use htmlspecialchars(); for cleaning input prefer a specific validate filter plus context-appropriate escaping at the point of use.

When should I use it?

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.

Practice

Practice
What does PHP Filters help with while working with data submission?
What does PHP Filters help with while working with data submission?
Was this page helpful?