filter_input()
Как PHP-функция filter_input() очищает и проверяет данные из GET, POST и cookie — FILTER_SANITIZE_*, FILTER_VALIDATE_* и возвращаемые значения.
Введение
filter_input() — встроенная PHP-функция, которая считывает одну внешнюю переменную из $_GET, $_POST, cookie, окружения сервера или getenv() и в один шаг пропускает её через фильтр. Фильтр либо очищает значение (удаляет или экранирует нежелательные символы), либо проверяет его (убеждается, что оно соответствует ожидаемому формату, и в противном случае отклоняет).
Главная причина использовать filter_input() вместо прямого обращения к $_GET['x'] — это безопасность по архитектуре: вы никогда не получаете в руки сырой суперглобальный массив, функция корректно сообщает об отсутствии переменной, а фильтр применяется в момент чтения значения. На этой странице рассматриваются синтаксис, разница между очисткой и проверкой, три возможных возвращаемых значения и полный пример обработки формы.
Нужно отфильтровать значение, которое уже хранится в переменной (а не в суперглобальном массиве)? Используйте
filter_var(). Для фильтрации нескольких полей сразу см.filter_input_array().
Синтаксис
filter_input(int $type, string $var_name, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed| Параметр | Обязательный | Описание |
|---|---|---|
$type | Да | Источник входных данных: INPUT_GET, INPUT_POST, INPUT_COOKIE, INPUT_SERVER или INPUT_ENV. |
$var_name | Да | Имя переменной для чтения, например 'email'. |
$filter | Нет | Идентификатор фильтра, например FILTER_VALIDATE_EMAIL. По умолчанию FILTER_DEFAULT (без фильтрации). |
$options | Нет | Ассоциативный массив параметров/флагов или битовая маска флагов. Используется для диапазонов, значений по умолчанию, regexp и т. д. |
Возвращаемые значения
filter_input() имеет три возможных возвращаемых значения, и их различение — главная причина использовать эту функцию:
- отфильтрованное значение при успехе;
false, если фильтрация (проверка) не прошла;null, если переменная отсутствует в запрошенном источнике входных данных.
Поскольку false и null означают разные вещи, сравнивайте с помощью ===, а не нестрогой проверки на истинность.
Очистка vs. проверка
Это наиболее распространённый источник путаницы, поэтому делайте выбор осознанно:
- Очистка (
FILTER_SANITIZE_*) — очищает значение и возвращает очищенную строку. Такой фильтр почти никогда «не проваливается»; он просто удаляет или экранирует символы. - Проверка (
FILTER_VALIDATE_*) — проверяет значение и при успехе возвращает его без изменений, а при неудаче —false. Используйте её, когда поле имеет строгий формат (email, целое число, URL, boolean).
FILTER_SANITIZE_STRINGбыл удалён в PHP 8.0. Используйте вместо негоFILTER_SANITIZE_FULL_SPECIAL_CHARS(илиhtmlspecialchars()при выводе).
Очистка входных данных
Пример ниже считывает поле name из POST-запроса и экранирует все специальные HTML-символы, чтобы значение было безопасно сохранять и выводить позже.
<?php
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
if ($name === null) {
$name = ''; // field was not submitted at all
}
echo $name;FILTER_SANITIZE_FULL_SPECIAL_CHARS HTML-кодирует все специальные символы (аналогично htmlspecialchars() с ENT_QUOTES), поэтому <b>Joe</b> превращается в <b>Joe</b>.
Проверка входных данных
Для полей с фиксированным форматом используйте проверку вместо очистки. Здесь FILTER_VALIDATE_EMAIL возвращает адрес при успехе или false при неудаче:
<?php
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === null) {
echo "No email submitted.";
} elseif ($email === false) {
echo "Invalid email address.";
} else {
echo "Valid email: $email";
}Проверка чисел с параметрами
Четвёртый параметр позволяет ограничить допустимые значения. Следующий код принимает целочисленный номер страницы, только если он находится в диапазоне от 1 до 100, и при неудаче возвращает 1:
<?php
$page = filter_input(INPUT_GET, 'page', FILTER_VALIDATE_INT, [
'options' => [
'min_range' => 1,
'max_range' => 100,
'default' => 1, // returned when validation fails
],
]);
echo "Page: $page";Полный пример формы
В реальном запросе каждое поле считывается непосредственно из источника входных данных:
<?php
$name = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_FULL_SPECIAL_CHARS);
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
$age = filter_input(INPUT_POST, 'age', FILTER_VALIDATE_INT, [
'options' => ['min_range' => 0, 'max_range' => 120],
]);
$errors = [];
if ($email === false) {
$errors[] = 'Invalid email.';
}
if ($age === false) {
$errors[] = 'Age must be a whole number between 0 and 120.';
}
if ($errors) {
echo implode("\n", $errors);
} else {
echo "Name: $name\nEmail: $email\nAge: $age\n";
}При корректной отправке (name=<b>Jane</b>, [email protected], age=34) будет выведено:
Name: <b>Jane</b>
Email: [email protected]
Age: 34Примечание:
filter_input()читает переменные, которые PHP захватил из реального HTTP-запроса, а не значения, позже присвоенные$_GET/$_POSTв коде. Это защищает от подделки, но при этом функция возвращаетnullдля каждого поля, если скрипт запускается из командной строки без реального запроса — проверяйте входные фильтры с помощьюfilter_var()на тестовой строке.
Когда использовать
Используйте filter_input() всякий раз, когда значение поступает в ваше приложение извне:
- Строки запроса и формы — получайте поля
INPUT_GET/INPUT_POSTс подходящим валидатором вместо того, чтобы доверять сырым суперглобальным переменным. - Пагинация, идентификаторы, цены —
FILTER_VALIDATE_INT/FILTER_VALIDATE_FLOATс ограничением диапазона отклоняет выходящие за пределы или нечисловые данные до передачи в запрос. - Контактные формы —
FILTER_VALIDATE_EMAILиFILTER_VALIDATE_URLпроверяют формат на входе. См. подробный разбор в Проверка PHP-форм.
Фильтрация на входе позволяет хранить логику проверки в одном месте и отделяет её от бизнес-логики, что делает код более читаемым, тестируемым и удобным для аудита. Полный список доступных фильтров см. в PHP Filters.
Заключение
filter_input() считывает одну внешнюю переменную и фильтрует её в одном чётко определённом шаге. Используйте фильтр FILTER_VALIDATE_*, когда поле имеет строгий формат, и FILTER_SANITIZE_*, когда нужно лишь очистить значение; всегда сравнивайте результат через ===, чтобы отличить отсутствующую переменную (null) от не прошедшей проверку (false).