Розширення ExpressionLanguage
Дата оновлення перекладу 2022-11-12
Розширення 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 [
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, [
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);
}
}