Супервалидация пользовательских данных

версия для печати

Задача: обработать данные с формы обратной связи. А там полей штук 30(!), это форма запроса кредита. Решение в лоб - разбирать массив и валидировать каждое значение, - это жесть. Выход в использовании возможностей php-функций filter_*_array(). Там много заморочек, я более-менее разобрался с этим семейством. Пищу здесь, чтоб в следующий раз не шариться в исходниках.

Пример не относится к банковской системе, он интереснее :)

if (!empty($_POST)) {
    $filters = array(
        'id'      => array('filter'  => FILTER_VALIDATE_INT,
                           'options' => array('min_range' => 0,),
                     ),
                        
        'name'    => array('filter' => FILTER_SANITIZE_STRING,
                           'flags'  => FILTER_FLAG_NO_ENCODE_QUOTES,
                     ),
        'orient'  => array('filter'  => FILTER_CALLBACK, 
                           'options' => array('PDFPattern', 'filterOrientation')
                     ),
        'content' => FILTER_UNSAFE_RAW, //без доп.флагов можно просто 'null' указать.
        'alias'   => null,              //без проверки

        //... и остальные n-цать полей ...

    );

    $post = array_intersect_key($_POST, $filters); //оставляем только ожидаемые элементы 
    $post = filter_var_array($post, $filters);     //дезинфекция
    $post = array_map('addslashes', $post);        //экранируем кавычки для записи в БД

    extract($post); 

    if (!isset($id)) { die ('Error: wrong id'); }

    //... Отдельные шаманства над $content и $alias ...
    //... запись в БД ...
}

Если не нужно разбирать в переменные, тогда проще:

//    $post = array_intersect_key($_POST, $filters);
    $_POST = filter_input_array(INPUT_POST, $filters); //дезинфекция
    $_POST = array_map('addslashes', $_POST);          //экранируем кавычки для записи в БД
//    extract($post); 

Обратите внимание, что filter_input_array(INPUT_POST, ...) работает с исходным массивом $_POST, т.е. любые его изменения в скрипте будут проигнорированы. В то же время, filter_var_array() принимает любой массив. Я вообще не понимаю, зачем нужна первая функция :)

Для MySQL предпочительнее использовать mysqli_real_escape_string() вместо addslashes(). Если вы еще пользуете расширение php_MySQL (без i), то рекомендую озадачиться рефакторингом, ибо оно устарело начиная с версии PHP 5.5.0, и будет удалено в дальнейшем.

---

Флаги FILTER_REQUIRE_ARRAY и FILTER_FORCE_ARRAY полезны, когда POST-параметр передан, как массив, например:

<select name="items[]" multiple>
    <option> ...
    <option> ...
</select>

Флаги объединяются вертикальной чертой

$filters = array(
    'items' => array('filter'  => FILTER_VALIDATE_INT,
                     'flags'   => FILTER_REQUIRE_ARRAY | FILTER_FORCE_ARRAY,
                     'options' => array('min_range' => 1, 'max_range' => 7),
                    ),
...
);

При этом валидатор возращает значение в массиве:

'items' => 
    array (size=3)
        0 => int 3
        1 => false    //"левое" значение. Не прошло валидацию.
        2 => int 6
r

Замечание: при ипользовании флага FILTER_FORCE_ARRAY любые данные будут возращены как массив, не зависимо от типа входящих данных.

---

Фильтры FILTER_VALIDATE_INT и FILTER_SANITIZE_NUMBER_INT выполняют разные задачи. Валидатор проверяет значение и приводит его к числовому типу либо возращает возращает логическое false. Дезинфекция только убирает из значения нечисловые символы, при этом никак не преобразует тип данных. Т.е. если число передано в строке (например через $_POST), то в строке оно и останется.

Валидация параметра 'orient' из примера выше использует классовую callback-функцию. Использование callback-функций дает большие возможности. Например, можно создать функцию, проверяющую данные регулярным выражением. В настройке фильтров валидации вызывать эту функцию и передавать параметром нужную регулярку.

[1oo%, EoF]

Понравилась статья? Расскажите о ней друзьям:


Комментарии

Показать/скрыть правила
Имя
[i] [b] [u] [s] [url]
:-) ;-) :D *lol* 8-) :-* :-| :-( *cry* :o :-? *unsure* *oops* :-x *shocked* *zzz* :P *evil*

Осталось 1000 символов.
Код защиты от спама Обновить код
Каждый комментарий проходит ручную модерацию. 100% фильтрация спама.
Для работы модуля комментариев включите javaScript

Продвижение
Время
Метки