7.2. Zend_Filter_Input

7.2.1. Введение

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

  • Разработчики

    Хотя фильтрация входных данных всегда требует некоторых усилий, разработчикам нужна уверенность в целостности их данных без добавления излишней сложности в их код. Zend_Filter_Input предлагает простые методы для наиболее частых случаев применения, расширяемые для особых случаев, и строгое соглашение по наименованию, способствующее ясности кода.

  • Менеджеры

    Менеджеры всех типов, которым необходим постоянный контроль за большой группой разрабочиков, могут принудить разработчиков к систематичному подходу к фильтрации входных данных посредством ограничения или исключения доступа к необработанным входным данным.

  • Аудиторы

    Тем, кто проверяет код приложения, нужно быстрое и достоверное распознавание, где и когда разрабочик использует необработанные входные данные. Свойства, которые способствуют ясности кода, еще оказывают помощь аудиторам тем, что обеспечивают четкую различимость разных подходов к фильтрации входных данных.

Есть множество подходов к фильтрации входных данных и средств, применяемых разработчиками PHP. Фильтрация по "белому списку", по "черному списку", регулярные выражения, условные операторы, встроенные функции PHP - только несколько примеров из всего разнообразия подходов к фильтрации входных данных. Zend_Filter_Input объединяет все эти средства в единый API с единообразным поведением и строгим соглашением по наименованию. Все эти методы следуют простому правилу - если данные являются допустимыми, то они возвращаются, иначе возвращается FALSE. Экстремально просто.

7.2.1.1. Фильтрация по "белому списку"

Методы для фильтрации по "белому списку" начинаются с префикса test, как, например, testAlpha() и testEmail(). Эти методы проверяют соответствие входных данных предопределенному критерию и возвращают данные, только если они соответствуют этому критерию. Если не соответствуют, то возвращается FALSE. Следующий простой пример демонстрирует это:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    
    if ($alphaName = $filterPost->testAlpha('name')) {
        /* $alphaName содержит только алфавитные символы. */
    } else {
        /* $alphaName имеет значение FALSE. */
    }
    
    ?>
            

В этом подходе мы перестраховываемся, производя оценку возвращаемого значения как булев тип. Если вы хотите отличать значения, которые при преобразовании в булев тип рассматриваются как FALSE (такие, как целочисленное значение 0, пустая строка), то можете производить строгое сравнение с FALSE:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $alphaName = $filterPost->testAlpha('name');
    
    if ($alphaName !== FALSE) {
        /* $alphaName содержит только алфавитные символы. */
    } else {
        /* $alphaName === FALSE */
    }
    
    ?>
            

7.2.1.2. "Слепая" фильтрация

Методы для "слепой" фильтрации начинаются с префикса get, как, например, getAlpha() и getDigits(). Эти методы не проверяют входные данные, вместо этого возвращают те его части, которые считаются корректными. Например, getAlpha() возвращает только алфавитные символы, если они есть. (Если их нет, то остаточная строка будет пустой.) Следующий простой пример демонстрирует это:

    <?php
    
    /* $_POST['username'] = 'John123Doe'; */
    
    $filterPost = new Zend_Filter_Input($_POST);
    $alphaUsername = $filterPost->getAlpha('username');
    
    /* $alphaUsername = 'JohnDoe'; */
    
    ?>
            

7.2.1.3. Фильтрация по "черному списку"

Методы для фильтрации по "черному списку" начинаются с префикса no, как, например, noPath(). Эти методы идентичны методам для "слепой" фильтрации, за исключением того, что критерии, которым они следуют, основаны на том, что считается недопустимым, а не на том, что считается допустимым. Недопустимые данные удаляются и возвращаются оставшиеся данные (рассматриваемые как допустимые). Следующий простой пример демонстрирует это:

<?php
    
/* $_POST['comment'] = '<b>I love PHP!</b>'; */

$filterPost = new Zend_Filter_Input($_POST);
$taglessComment = $filterPost->noTags('comment');

/* $taglessComment = 'I love PHP!'; */
    
?>

7.2.2. Теория по использованию

Zend_Filter_Input объединяет различные подходы к фильтрации входных данных в единый API с единообразным поведением и строгим соглашением по наименованию (смотрите Раздел 7.2.1, «Введение»). Эти характеристики ставят Zend_Filter_Input на один уровень с существующими решениями, но не оказывают дальнейшей поддержки тем, кто требует большей структурности или жесткого подхода. Тем не менее, по умолчанию Zend_Filter_Input осуществляет контролируемый доступ к входным данным.

Поддерживаются два синтаксиса. В подходе по умолчанию (строгом) единственный аргумент, передаваемый конструктору, - массив для фильтрации:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $email = $filterPost->testEmail('email');
    
    ?>
        

Zend_Filter_Input устанавливает значение переданного массива ($_POST) в NULL, поэтому дальнейший прямой доступ становится невозможным. (Необработанные данные доступны только через метод getRaw(), который намного легче контролировать и/или сделать недействительным.)

В дополнительном (нестрогом) подходе конструктору в качестве второго аргумента передается FALSE:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    $email = $filterPost->testEmail('email');
    
    ?>
        

Использование фильтра будет таким же, за исключеним того, что Zend_Filter_Input не устанавливает значение исходного массива ($_POST) в NULL, так что разработчики по-прежнему могут иметь прямой доступ. Этот подход лишен привлекательности строгого подхода.

Zend_Filter_Input спроектирован для работы с массивами. Многие источники входных данных уже предусмотрены в суперглобальных массивах ($_GET, $_POST, $_COOKIE и т.д.), массивы часто используются в качестве конструкции для хранения входных данных из других источников. Если вам нужно фильтровать отдельные значения, см. Глава 7, Zend_Filter.

7.2.3. Примеры использования

Строгая фильтрация по "белому списку" (предпочтительная):

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    
    if ($email = $filterPost->testEmail('email')) {
        /* $email имеет допустимый формат. */
    } else {
        /* $email имеет недопустимый формат. */
    }
    
    ?>
        

Строгая "слепая" фильтрация:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $alphaName = $filterPost->getAlpha('name');
    
    ?>
        

Строгая фильтрация по "черному списку":

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST);
    $taglessComment = $filterPost->noTags('comment');
    
    ?>
        

Нестрогая фильтрация по "белому списку":

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    
    if ($email = $filterPost->testEmail('email')) {
        /* $email имеет допустимый формат. */
    } else {
        /* $email имеет недопустимый формат. */
    }
    
    ?>
        

Нестрогая "слепая" фильтрация:

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    $name = $filterPost->getAlpha('name');
    
    ?>
        

Нестрогая фильтрация по "черному списку":

    <?php
    
    $filterPost = new Zend_Filter_Input($_POST, FALSE);
    $comment = $filterPost->noTags('comment');
    
    ?>