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

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

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 и их «массивные» аналоги, вы быстро получите надёжную и чистую схему валидации и фильтрации данных. Добавьте нормализацию, строгие сравнения и безопасный вывод — и ваши формы станут предсказуемыми, а код — устойчивым и безопасным.

    Источник

    НЕТ КОММЕНТАРИЕВ

    Оставить комментарий