PHP filter_var и filter_input: понятное руководство по валидации и фильтрации данных

Корректная обработка входных данных — основа безопасности и устойчивости приложения. В PHP для этого есть мощный и быстрый инструмент: фильтры из расширения filter — прежде всего функции filter_var и filter_input. Ниже — практическое руководство с примерами и советами, которое поможет вам настроить валидацию и фильтрацию данных «с нуля» правильно.
Валидация vs фильтрация: в чём разница
- Валидация — проверка соответствия значения правилам (например, это email? число от 1 до 100?).
- Фильтрация — «очистка» значения (удаление опасных символов, приведение типов, тримминг).
Важно: фильтрация не гарантирует валидность, а валидация не делает значение безопасным для вывода в HTML. Для вывода всегда используйте htmlspecialchars.
Ключевые функции фильтров PHP
- filter_input(type, name, filter, options) — берёт значение напрямую из источника (GET, POST, COOKIE, SERVER).
- filter_var(value, filter, options) — валидирует или фильтрует уже имеющееся значение.
- filter_input_array и filter_var_array — пакетная обработка набора полей по спецификации (массива правил).
Базовые примеры: email, число, bool, URL
Email из формы (POST)
$email = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);
if ($email === false) {
// Поле есть, но email невалиден
$error = 'Введите корректный email';
} elseif ($email === null) {
// Поле отсутствует в запросе
$error = 'Поле email обязательно';
} else {
// ОК — валидный email
}
Отличайте false (значение есть, но не прошло валидацию) от null (значения нет). Если нужно различать случаи строгее — используйте filter_has_var.
ID из URL (GET) — только целое и от 1
if (!filter_has_var(INPUT_GET, 'id')) {
http_response_code(400);
exit('Отсутствует параметр id');
}
$id = filter_input(
INPUT_GET,
'id',
FILTER_VALIDATE_INT,
[
'options' => ['min_range' => 1],
'flags' => FILTER_NULL_ON_FAILURE
]
);
if ($id === null) {
http_response_code(400);
exit('Некорректный id');
}
// $id — гарантированно int >= 1
Булево из формы
$isActive = filter_input(INPUT_POST, 'active', FILTER_VALIDATE_BOOL, FILTER_NULL_ON_FAILURE);
if ($isActive === null) {
// Не удалось распознать как true/false
}
// $isActive — bool или null
Проверка URL
$url = filter_input(INPUT_POST, 'website', FILTER_VALIDATE_URL, [
'flags' => FILTER_FLAG_PATH_REQUIRED | FILTER_FLAG_QUERY_REQUIRED
]);
if ($url === false || $url === null) {
$error = 'Укажите полный URL с путем и параметрами (например, https://site.com/page?x=1)';
}
Фильтрация текста и безопасный вывод
Ранее популярный FILTER_SANITIZE_STRING устарел (deprecated в PHP 8.1, удалён в 8.3). Вместо него используйте понятные и явные операции:
- trim — убрать пробелы по краям
- strip_tags — удалить HTML-теги, если нужно
- mb_substr — ограничить длину
- htmlspecialchars при выводе — защита от XSS
$nameRaw = filter_input(INPUT_POST, 'name', FILTER_UNSAFE_RAW) ?? '';
$name = trim(strip_tags($nameRaw));
$name = mb_substr($name, 0, 50);
if ($name === '') {
$error = 'Имя не может быть пустым';
}
// При выводе в HTML:
echo htmlspecialchars($name, ENT_QUOTES | ENT_SUBSTITUTE, 'UTF-8');
Помните: фильтры — про данные, escaping — про вывод. Это разные этапы защиты.
Обработка массивов полей: filter_input_array
Если у формы много полей, удобно применить правила сразу ко всем:
$spec = [
'email' => FILTER_VALIDATE_EMAIL,
'age' => [
'filter' => FILTER_VALIDATE_INT,
'options' => ['min_range' => 18, 'max_range' => 99],
'flags' => FILTER_NULL_ON_FAILURE,
],
'tags' => [
'filter' => FILTER_DEFAULT, // просто получить как есть
'flags' => FILTER_REQUIRE_ARRAY, // ожидаем массив
],
];
$data = filter_input_array(INPUT_POST, $spec);
// $data['email'] — валидный email или false/null
// $data['age'] — int или null
// $data['tags'] — массив строк
Если нужна «очистка» для элементов массива (например, trim для каждого тега), примените array_map после получения значений.
Валидируем числа с плавающей точкой и локаль
Для десятичных чисел учтите локаль: пользователь может ввести «1,5». Унифицируйте ввод, а затем валидируйте:
$priceRaw = filter_input(INPUT_POST, 'price', FILTER_UNSAFE_RAW) ?? '';
$priceNormalized = str_replace(',', '.', trim($priceRaw));
$price = filter_var($priceNormalized, FILTER_VALIDATE_FLOAT, [
'flags' => FILTER_NULL_ON_FAILURE,
]);
if ($price === null || $price <= 0) {
$error = 'Укажите корректную цену больше 0';
}
Частые ошибки и как их избежать
- Путаница между null и false. Используйте FILTER_NULL_ON_FAILURE и строгие сравнения (===).
- Слепая вера в фронтенд-валидацию. Всегда проверяйте данные на сервере.
- Использование устаревших фильтров. Не применяйте FILTER_SANITIZE_STRING и FILTER_CALLBACK (удалены в PHP 8.3).
- empty('0') == true. Для числовых полей валидируйте фильтрами и сравнивайте строго, иначе «0» может считаться «пустым».
- Отсутствие нормализации. Trim, замена запятых на точки, ограничение длины — повышают качество данных ещё до валидации.
Мини-утилита для проекта
function in_get_int(string $key, int $min = 1): ?int {
if (!filter_has_var(INPUT_GET, $key)) {
return null;
}
return filter_input(INPUT_GET, $key, FILTER_VALIDATE_INT, [
'options' => ['min_range' => $min],
'flags' => FILTER_NULL_ON_FAILURE,
]);
}
function in_post_email(string $key = 'email'): ?string {
$val = filter_input(INPUT_POST, $key, FILTER_VALIDATE_EMAIL);
return $val === false ? null : $val;
}
// Использование:
$id = in_get_int('id');
$email = in_post_email();
Куда двигаться дальше
Фильтры — это фундамент обработки входа. Далее вам пригодятся корректный экранирующий вывод, защита от CSRF и безопасная работа с БД через подготовленные выражения. Если хотите быстро закрыть пробелы и собрать всё в единую систему на реальных задачах — рекомендую Пройти практический курс «PHP и MySQL с Нуля до Гуру 3.0» — отличный путь прокачать PHP с нуля до уверенной разработки.
Итог
Используя filter_var, filter_input и их «массивные» аналоги, вы быстро получите надёжную и чистую схему валидации и фильтрации данных. Добавьте нормализацию, строгие сравнения и безопасный вывод — и ваши формы станут предсказуемыми, а код — устойчивым и безопасным.
-
-
Михаил Русаков
Комментарии (0):
Для добавления комментариев надо войти в систему.
Если Вы ещё не зарегистрированы на сайте, то сначала зарегистрируйтесь.