data types and standard library

Filters

PHP's filter functions help validate and normalise simple scalar input such as email addresses, integers, booleans, IP addresses, and URLs.

Filters are boundary tools. They help decide whether input is acceptable before it reaches business logic. They do not replace domain validation, authorisation, prepared SQL statements, or output escaping.

Validate email and integers

Use filter_var() when you already have a value, such as data from a request array, JSON payload, CSV row, or config file.

PHP example
<?php

declare(strict_types=1);

$email = 'nia@example.com';
$age = '27';

$validEmail = filter_var($email, FILTER_VALIDATE_EMAIL);
$validAge = filter_var($age, FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 18],
]);

echo $validEmail === false ? 'Invalid email' : 'Email accepted';
echo PHP_EOL;
echo $validAge === false ? 'Invalid age' : 'Age accepted';
echo PHP_EOL;

// Prints:
// Email accepted
// Age accepted

The return value is the filtered value or false. Use strict comparison with false so valid values such as 0 are not rejected accidentally.

Handle zero correctly

This is a common source of bugs.

PHP example
<?php

declare(strict_types=1);

$quantity = filter_var('0', FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 0],
]);

echo $quantity === false ? 'invalid' : 'valid quantity: ' . $quantity;
echo PHP_EOL;

// Prints:
// valid quantity: 0

Do not write if (!$quantity) for validation here. Zero may be a valid value.

Convert booleans carefully

Use FILTER_NULL_ON_FAILURE when you need to distinguish false from invalid input.

PHP example
<?php

declare(strict_types=1);

function parseBoolean(string $value): bool
{
    $parsed = filter_var($value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE);

    if ($parsed === null) {
        throw new InvalidArgumentException('Expected a boolean value.');
    }

    return $parsed;
}

echo parseBoolean('false') ? 'yes' : 'no';
echo PHP_EOL;

// Prints:
// no

This is useful for query parameters, config values, and feature flags.

Validate URLs with a policy

FILTER_VALIDATE_URL checks URL syntax. Your application still needs a policy for allowed schemes and hosts.

PHP example
<?php

declare(strict_types=1);

function requireHttpsUrl(string $url): string
{
    $validUrl = filter_var($url, FILTER_VALIDATE_URL);

    if ($validUrl === false) {
        throw new InvalidArgumentException('URL is invalid.');
    }

    $parts = parse_url($validUrl);

    if (($parts['scheme'] ?? '') !== 'https') {
        throw new InvalidArgumentException('URL must use HTTPS.');
    }

    return $validUrl;
}

echo requireHttpsUrl('https://example.com/callback') . PHP_EOL;

// Prints:
// https://example.com/callback

A syntactically valid URL can still be unsafe for your use case.

Sanitising is not the same as validating

Sanitising changes data. Validation accepts or rejects data. Be clear which behaviour you need.

PHP example
<?php

declare(strict_types=1);

$rawName = "  Nia Stone  \n";
$name = trim($rawName);

if ($name === '') {
    throw new InvalidArgumentException('Name is required.');
}

echo $name . PHP_EOL;

// Prints:
// Nia Stone

For HTML output, use escaping such as htmlspecialchars() at the output boundary. Do not rely on input filters to make later HTML safe.

Collect validation errors

Form handlers usually need all useful errors, not just the first one.

PHP example
<?php

declare(strict_types=1);

$input = [
    'email' => 'not-an-email',
    'age' => '17',
];

$errors = [];

if (filter_var($input['email'] ?? '', FILTER_VALIDATE_EMAIL) === false) {
    $errors['email'] = 'A valid email address is required.';
}

$age = filter_var($input['age'] ?? null, FILTER_VALIDATE_INT, [
    'options' => ['min_range' => 18],
]);

if ($age === false) {
    $errors['age'] = 'You must be at least 18.';
}

echo implode(' ', $errors) . PHP_EOL;

// Prints:
// A valid email address is required. You must be at least 18.

This shape maps directly to controllers and API validators.

What to remember

Filters are useful for simple scalar validation, but they are not a complete security layer. Use strict false checks, handle zero correctly, separate validation from output escaping, and add application rules on top of generic format checks.

Practice

Task: Validate a registration form

Write a small validator for registration form data.

Requirements

  • Use declare(strict_types=1);.
  • Accept an input array.
  • Require name to be a non-empty string after trimming.
  • Require email to pass FILTER_VALIDATE_EMAIL.
  • Require age to be an integer of at least 18.
  • Preserve 0 as a valid integer in the general validation style, even though it fails the age rule.
  • Return validated data and errors separately.
  • Print the errors for one invalid input.
  • Print the validated data for one valid input.
  • Include the expected output as comments in the same PHP code block.

Use strict comparisons against false when checking filter results.

Show solution
PHP example
<?php

declare(strict_types=1);

function validateRegistration(array $input): array
{
    $data = [];
    $errors = [];

    $name = trim((string) ($input['name'] ?? ''));

    if ($name === '') {
        $errors['name'] = 'Name is required.';
    } else {
        $data['name'] = $name;
    }

    $email = filter_var($input['email'] ?? '', FILTER_VALIDATE_EMAIL);

    if ($email === false) {
        $errors['email'] = 'A valid email address is required.';
    } else {
        $data['email'] = $email;
    }

    $age = filter_var($input['age'] ?? null, FILTER_VALIDATE_INT, [
        'options' => ['min_range' => 18],
    ]);

    if ($age === false) {
        $errors['age'] = 'You must be at least 18.';
    } else {
        $data['age'] = $age;
    }

    return [
        'data' => $data,
        'errors' => $errors,
    ];
}

$invalid = validateRegistration([
    'name' => ' ',
    'email' => 'not-an-email',
    'age' => '0',
]);

echo implode(' ', $invalid['errors']) . PHP_EOL;

$valid = validateRegistration([
    'name' => ' Nia Stone ',
    'email' => 'nia@example.com',
    'age' => '27',
]);

echo $valid['data']['name'] . ' / ' . $valid['data']['email'] . ' / ' . $valid['data']['age'] . PHP_EOL;

// Prints:
// Name is required. A valid email address is required. You must be at least 18.
// Nia Stone / nia@example.com / 27

The validator trims the name, validates email syntax, converts age to an integer, and keeps errors separate from accepted data. The age check uses === false, so the code does not confuse a valid integer zero with a filter failure.