Расширение ExpressionLanguage
Расширение ExpressionLanguage
ExpressionLanguage может быть расширен путём добавление пользовательских функций. Например, в фреймворке Symfony, безопасность имеет настраиваемые функции для проверки роли пользователя.
Note
Если вы хотите узнать, как использовать функции в выражении, см. "".
Регистрация функций
Функции регистрируются в каждом конкретном экземпляре ExpressionLanguage
.
Это означает, что функции могут быть использованы в любом выражении, выполняемом
этим экземпляром.
Для того, чтобы зарегистрировать функцию, используйте register(). Этот метод имеет 3 аргумента:
- name - Имя функции в выражении;
- compiler - Функция, выполняемая при компиляции выражения, использующего функцию;
- evaluator - Функция, выполняемая при оценке выражения.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
$expressionLanguage = new ExpressionLanguage();
$expressionLanguage->register('lowercase', function ($str) {
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str);
}, function ($arguments, $str) {
if (!is_string($str)) {
return $str;
}
return strtolower($str);
});
var_dump($expressionLanguage->evaluate('lowercase("HELLO")'));
// это выведет: hello
В дополнение к пользовательским аргументам функции, evaluator передатся
переменная arguments
в качестве первого аргумента, который эквивалентен
второму аргументу compile()
(например, "значения" при оценке выражения).
Использование поставщиков выражений
Когда вы используете в вашей библиотеке класс ExpressionLanguage
, вам
часто может хотеться добавить пользовательские функции. Чтобы сделать это,
вы можете создать новый поставщик выражений, создав класс, реализующий
ExpressionFunctionProviderInterface.
Этот интерфес требует одного метода: getFunctions(), который возвращает массив функций выражения (экземпляры ExpressionFunction) для регистрации:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
use Symfony\Component\ExpressionLanguage\ExpressionFunction;
use Symfony\Component\ExpressionLanguage\ExpressionFunctionProviderInterface;
class StringExpressionLanguageProvider implements ExpressionFunctionProviderInterface
{
public function getFunctions()
{
return array(
new ExpressionFunction('lowercase', function ($str) {
return sprintf('(is_string(%1$s) ? strtolower(%1$s) : %1$s)', $str);
}, function ($arguments, $str) {
if (!is_string($str)) {
return $str;
}
return strtolower($str);
}),
);
}
}
Tip
Чтобы создать функцию выражения из PHP функции со статическим методом fromPhp():
1
ExpressionFunction::fromPhp('strtoupper');
Функции с пространством имён поддерживаются, но они требуют второго аргумента для определения имени выражения:
1
ExpressionFunction::fromPhp('My\strtoupper', 'my_strtoupper');
Вы можете зарегистрировать поставщика, используя registerProvider() или используя второй аргумент конструктора:
1 2 3 4 5 6 7 8 9 10
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
// использование конструктора
$expressionLanguage = new ExpressionLanguage(null, array(
new StringExpressionLanguageProvider(),
// ...
));
// использование registerProvider()
$expressionLanguage->registerProvider(new StringExpressionLanguageProvider());
Tip
Рекомендуется создать ваш собственный класс ExpressionLanguage
в вашей
библиотеке. Теперь вы можете добавлять выражение, переопределяя конструктор:
1 2 3 4 5 6 7 8 9 10 11 12 13
use Psr\Cache\CacheItemPoolInterface;
use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;
class ExpressionLanguage extends BaseExpressionLanguage
{
public function __construct(CacheItemPoolInterface $parser = null, array $providers = array())
{
// добавляет к поставщику по умолчанию, чтобы позволить пользователем легко его переопределять
array_unshift($providers, new StringExpressionLanguageProvider());
parent::__construct($parser, $providers);
}
}