Содержание


Inflector


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



 

Zend\Filter\Inflector это универсальный инструмент, предназначенный для флексий (словоизменений) строк на основе правил для заданной цели.

 

Допустим, вам может понадобиться преобразовать Смешенную Нотацию или вербльюжью Нотацию в путь в файловой системе; для читабельности, политики операционной системы, или по другим причинам, вам также может понадобиться перевести это в нижний регистр, или же вы захотите разделить слова дефисом ('-'). Инфлектор сделает это для вас.

 

Zend\Filter\Inflector реализует интерфейс Zend\Filter\FilterInterface; вы совершите флексию вызовом метода filter() экземпляра объекта.

 

Преобразование Смешанной Нотации и верблюжьей Нотации в другой формат

$inflector = new Zend\Filter\Inflector('pages/:page.:suffix');
$inflector->setRules(array(
    ':page'  => array('Word\CamelCaseToDash', 'StringToLower'),
    'suffix' => 'html'
));
$string   = 'camelCasedWords';
$filtered = $inflector->filter(array('page' => $string));
// pages/camel-cased-words.html
$string   = 'this_is_not_camel_cased';
$filtered = $inflector->filter(array('page' => $string));
// pages/this_is_not_camel_cased.html
 


Эксплуатация

 

Инфлектору требуется цель и одно или более правил. Цель, в своей основе, это строка которая определяет метки-заполнители для переменных, которые вы хотите подвергнуть подстановке. Они заданы префиксами с помощью ':'.

 

При вызове filter() вы передаете в виде массива пары ключей и значений, соответствующие переменным в цели.

 

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

 

Например, вы можете использовать любую конкретную реализацию Zend\Filter; однако, вместо того, чтобы ссылаться на них, как 'Zend\Filter\Alpha' или 'Zend\Filter\StringToLower', вы должны указать только 'Alpha' или 'StringToLower'.

 


Использование заказных фильтров

 

Zend\Filter\Inflector использует Zend\Filter\FilterPluginManager для управления загрузкой фильтров, использующихся для флексии. По умолчанию, фильтры можно зарегистрировать с помощью Zend\Filter\FilterPluginManager. Чтобы получить доступ к фильтрам с тем же префиксом, но расположенным глубже в иерархии, таким, как различные фильтры Word, просто уберите префикс Zend\Filter:

// use ZendFilterWordCamelCaseToDash as a rule
$inflector->addRules(array('script' => 'WordCamelCaseToDash'));
 

Для использования заказных фильтров вы можете выбрать из двух вариантов: ссылки на их полное имя класса (например, My\Custom\Filter\Mungify), или манипулирование экземпляром FilterPluginManager.

$filters = $inflector->getPluginManager();
$filters->addInvokableClass('mungify', 'My\Custom\Filter\Mungify');
 


Настройка цели инфлектора

 

Цель инфлектора - это некоторая строка с метками-заполнителями для переменных. Метки-заполнители приобретают форму идентификаторов, по умолчанию это двоеточие (':'), вслед за которыми указывается имя переменной: ':script', ':path', и т.д. Метод filter() ищет идентификатор и идущее за ним имя переменной, которую необходимо заменить.

 

Вы можете изменить идентификатор с помощью метода setTargetReplacementIdentifier() или путем его передачи в качестве третьего аргумента в конструктор:

// С помощью конструктора:
$inflector = new Zend\Filter\Inflector('#foo/#bar.#sfx', null, '#');
 
// С помощью методов доступа:
$inflector->setTargetReplacementIdentifier('#');
 

Обычно цель устанавливают с помощью конструктора. Тем не менее, вы можете пере установить цель позже (например, чтобы изменить стандартный инфлектор в компонентах ядра, таких, как ViewRenderer или Zend\Layout). Для этих целей может быть использован метод setTarget():

$inflector = $layout->getInflector();
$inflector->setTarget('layouts/:script.phtml');
 

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

class Foo
{
    /**
     * @var string Цель инфлектора (вышеупомянутый член класса, позволяющий держать цель скорректированной)
     */
    protected $_target = 'foo/:bar/:baz.:suffix';
 
    /**
     * Конструктор
     * @return void
     */
    public function __construct()
    {
        $this->_inflector = new Zend\Filter\Inflector();
        $this->_inflector->setTargetReference($this->_target);
    }
 
    /**
     * Установить цель; обновление цели в инфлекторе
     *
     * @param  string $target
     * @return Foo
     */
    public function setTarget($target)
    {
        $this->_target = $target;
        return $this;
    }
}
 

Правила инфлексий

 

Как уже упоминалось во введении, существует два типа правил: статические и правила на основе фильтров.

 

Примечание

 

Важно отметить, что независимо от метода, которым вы добавляете правила в инфлектор, либо один-к-одному, либо все-в-одном, порядок добавления очень важен. Более специфические имена, или имена, которые могут включать имена других правил, должны быть добавлены перед менее специфическими именами. Для примера рассмотрим два правила с именами 'moduleDir' и 'module', правило 'moduleDir' должно появиться перед 'module', поскольку 'module' содержится в 'moduleDir'. Если правило 'module' добавить перед 'moduleDir', 'module' частично совпадет с 'moduleDir', и это будет обработано, оставляя 'Dir' внутри цели без применения флексии.

 

Статические правила

 

Статические правила выполняют простую подстановку строки, используйте их, когда у вас есть сегмент в цели, который, как правило, будет статическим, но вы хотите позволить разработчику модифицировать его. Используйте метод setStaticRule(), чтобы устанавливать или модифицировать правила:

$inflector = new Zend\Filter\Inflector(':script.:suffix');
$inflector->setStaticRule('suffix', 'phtml');
// изменение это позже:
$inflector->setStaticRule('suffix', 'php');
 

Помимо самой цели, вы можете также связать статическое правило ссылкой, что позволит вам корректировать одну переменную вместо того, чтобы вызывать метод; это часто полезно, если ваш класс использует инфлектор внутренне и вы не хотите, чтобы вашим пользователям нужно было бы вызывать инфлектор, чтобы скорректировать его. Для этого используется метод setStaticRuleReference():

class Foo
{
    /**
     * @var string Суффикс
     */
    protected $_suffix = 'phtml';
 
    /**
     * Конструктор
     * @return void
     */
    public function __construct()
    {
        $this->_inflector = new Zend\Filter\Inflector(':script.:suffix');
        $this->_inflector->setStaticRuleReference('suffix', $this->_suffix);
    }
 
    /**
     * Установить суффикс, обновить статическое правило суффикса в инфлекторе
     *
     * @param  string $suffix
     * @return Foo
     */
    public function setSuffix($suffix)
    {
        $this->_suffix = $suffix;
        return $this;
    }
}
 

Фильтрующие правила инфлектора

 

Фильтры Zend\Filter также могут быть использованы как правила инфлектора. Как и статические правила, они связаны с целевой переменной, в отличии от статических правил, вы можете использовать несколько фильтров при флексии. Эти фильтры обрабатываются в определенном порядке, так что будьте осторожны и регистрируйте их в том порядке, который имеет смысл для данных, которые вы получите.

 

Правила могут быть добавлены с помощью методов setFilterRule()  (который перезаписывает любые предшествующие правила для этой переменной) или addFilterRule() (который добавляет новые правила к любым существующим правилам для этой переменной). Фильтры указываются одним из следующих способов:

Строкой. Строкой может быть имя класса или сегмент имени класса минус любой префикс, установленный в загрузчик плагинов инфлектора (по умолчанию, минус префикс 'Zend\Filter').

Объектом фильтра. Любой экземпляр объекта, реализующего интерфейс Zend\Filter\FilterInterface может быть передан в качестве фильтра.

Массивом. Массив из одной или более строк или объектов фильтра, как указано выше.

$inflector = new Zend\Filter\Inflector(':script.:suffix');
// Установить правило использования фильтра Zend\Filter\Word\CamelCaseToDash
$inflector->setFilterRule('script', 'Word\CamelCaseToDash');
// Добавить правило для перевода строки в нижний регистр
$inflector->addFilterRule('script', new Zend\Filter\StringToLower());
// Установить несколько правил
$inflector->setFilterRule('script', array(
    'WordCamelCaseToDash',
    new Zend\Filter\StringToLower()
));
 

Установка нескольких правил сразу

 

Как правило, проще установить несколько правил сразу, чем настраивать одну переменную и ее правила флексии несколько раз. Методы Zend\Filter\Inflector addRules() и setRules() позволяют сделать это.

 

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

префикс ':'  - правила фильтрации

без префикса - статическое правило

 

Установка нескольких правил одновременно

// С этой нотацией можно также использовать setRules()
$inflector->addRules(array(
    // правила фильтрации:
    ':controller' => array('CamelCaseToUnderscore','StringToLower'),
    ':action'     => array('CamelCaseToUnderscore','StringToLower'),
    // Статические правила:
    'suffix'      => 'phtml'
));
 

Полезные методы

 

Zend\Filter\Inflector  имеет ряд вспомогательных методов для получения и установки загрузчика плагинов, манипулирования и получения правил, контроля в случаи выброса исключений.

setPluginManager() можно использовать, когда вы настроили собственный экземпляр Zend\Filter\FilterPluginManager и хотите использовать его с Zend\Filter\Inflector; getPluginManager() возвращает одно текущее значение.

setThrowTargetExceptionsOn() можно использовать для контроля того, будет или нет генерироваться исключение в методе filter(), если заданный идентификатор для замены, переданный ему, не найден в цели. По умолчанию исключение не генерируется. Метод  isThrowTargetExceptionsOn() указывает текущее значение.

getRules($spec = null) можно использовать для получения всех зарегистрированных правил для всех переменных, или только правил для одной переменной.

getRule($spec, $index) извлекает одно правило для заданной переменной; это может пригодиться для извлечения конкретного правила фильтрации для переменной, у которой есть цепочка фильтров. $index должен быть задан.

clearRules() приводит к удалению всех зарегистрированных на данный момент правил.

 


Использование объекта с интерфейсом Traversable или массива с Zend\Filter\Inflector

 

Вы можете использовать объект с интерфейсом Traversable или массив для установки правил или иных состояний объекта в ваш инфлектор, либо путем передачи Traversable-объекта или массива в конструктор, либо методом setOptions(). Могут быть указаны следующие параметры:

target определенная цель флексии.

pluginManager определенный экземпляр или расширение Zend\Filter\FilterPluginManager, используемый для получения плагинов; кроме того, вы можете указать имя класса, который наследует FilterPluginManager.

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

targetReplacementIdentifier задает символ, используемый для идентификации заменяемых переменных в целевой строке.

rules, правила, заданные массивом правил флексии; массив должен состоять из ключей с соответствующими им значениями, либо массивами значений, в соответствии с addRules().

 



Использование объекта с интерфейсом Traversable или массива для Zend\Filter\Inflector

// С использованием конструктора:
$options; // implements Traversable
$inflector = new Zend\Filter\Inflector($options);
 
// Или с использованием setOptions():
$inflector = new Zend\Filter\Inflector();
$inflector->setOptions($options);