Содержание


Filter


Фильтры, ЗФ2, Zend Framework 2, ZF2, ру, ru




Введение



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

Что такое фильтр?



В реальном мире фильтр обычно используется для удаления поступающих нежелательных элементов, а поступающие желаемые элементы проходят через фильтр на выход (например, кофе). В таких случаях фильтр - это оператор, который обрабатывает поступающий набор путем его выборки. Этот тип фильтрации полезен для веб-приложений - удаление некорректного ввода, лишних пробелов и т.д.
Можно расширить это базовое определение фильтра обработкой поступающих (данных) путем их преобразования. Часто встречаемое в веб-приложениях преобразование - это экранирование HTML сущностей. Например, если поля формы машинально заполняются ненадежными данными (например, через веб-браузер), это значение должно быть либо свободно от HTML сущностей, либо содержать экранированные HTML сущности, во избежание нежелательного поведения и уязвимостей. Чтобы удовлетворить это требование, HTML сущности, появляющиеся на входе, должны быть либо удалены, либо экранированы. Конечно, то, какой подход является наиболее уместным, зависит от ситуации. Фильтр, который удаляет HTML сущности, действует в рамках первого определения фильтра - оператор, который обрабатывает поступающий набор путем его выборки. Фильтр, который экранирует HTML сущности, в свою очередь, преобразовывает ввод (например, "&" трансформируется в “&”). Поддержка таких случаев использования важна для веб-разработчиков, и "фильтрация" в контексте использования ZendFilter означает выполнение некоторых преобразований над входными данными.

Основы использования фильтров



Имеющееся определение фильтра дает основу для ZendFilterFilterInterface, с единственным обязательным методом filter() для реализации класса фильтра.
Ниже приведен пример использования фильтра с двумя входными данными, амперсанд (&) и двойные кавычки (“):
$htmlEntities = new Zend\Filter\HtmlEntities();
 
echo $htmlEntities->filter('&'); // &
echo $htmlEntities->filter('"'); // "

Кроме того, если фильтр наследует ZendFilterAbstractFilter (как и все фильтры "из-коробки"), вы можете использовать их следующим образом:
$strtolower = new Zend\Filter\StringToLower;
 
echo $strtolower('I LOVE ZF2!'); // i love zf2!
$zf2love = $strtolower('I LOVE ZF2!');

Использование StaticFilter:



Если загрузка определенного класса фильтров и создание экземпляра класса неудобна, вы можете использовать StaticFilter и его метод execute() в качестве альтернативного стиля вызова. Первым аргументом этого метода является значение входных данных, которое вы передаете в метод filter(). Вторым аргументом является строка, которая соответствует базовому имени класса фильтра относительно пространства имен ZendFilter. Метод execute() автоматически загружает класс, создает его экземпляр, и применяет метод filter() ко входным данным.
echo StaticFilter::execute('&', 'HtmlEntities');
echo StaticFilter::execute('"',
                           'HtmlEntities',
                           array('quotestyle' => ENT_QUOTES));

Использование статики более удобно для вызова специального фильтра, но если нужно выполнить фильтрацию множества входных данных, более эффективным будет следование первому примеру выше, создавая экземпляр объекта фильтра и вызывая метод filter().
Кроме того, класс FilterChain позволяет инстанцировать и выполнить несколько фильтров и классов валидации по требованию для обработки наборов входных данных. См. FilterChain.

Вы можете установить и получить FilterPluginManager для StaticFilter, чтобы внести изменения в стандартные классы фильтров.
$pluginManager = StaticFilter::getPluginManager()->setInvokableClass(
    'myNewFilter', 'MyCustomFilterMyNewFilter'
);
 
StaticFilter::setPluginManager(new MyFilterPluginManager());

Это полезно при добавлении пользовательских фильтров, которые будут использоваться StaticFilter.

Двойная фильтрация.


При использовании двух фильтров друг за другом, вы должны иметь в виду, что часто невозможно получить оригинальный выход с помощью противоположных фильтра. Возьмем следующий пример:
$original = "my_original_content";
 
// Attach a filter
$filter   = new Zend\Filter\Word\UnderscoreToCamelCase();
$filtered = $filter->filter($original);
 
// Use it's opposite
$filter2  = new Zend\Filter\Word\CamelCaseToUnderscore();
$filtered = $filter2->filter($filtered)

Приведенный выше пример кода может создать впечатление, что вы получите оригинальный выход после применения второго фильтра. Но, если подумать логически, это не тот случай. После применения первого фильтра my_original_content будет изменен на MyOriginalContent. Но после применения второго фильтра результат станет My_Original_Content.
Как вы можете видеть, не всегда можно получить оригинальный выход с помощью противоположного фильтра. Это зависит как от самого фильтра, так и от входных данных.