Extending the ExpressionLanguage ¶
The ExpressionLanguage can be extended by adding custom functions. For instance, in the Symfony Framework, the security has custom functions to check the user's role.
Note
If you want to learn how to use functions in an expression, read "The Expression Syntax".
Registering Functions ¶
Functions are registered on each specific ExpressionLanguage
instance.
That means the functions can be used in any expression executed by that
instance.
To register a function, use register(). This method has 3 arguments:
- name - The name of the function in an expression;name - 式内の関数の名前。
- compiler - A function executed when compiling an expression using the
function;compiler - 関数を使用して式をコンパイルするときに実行される関数。
- evaluator - A function executed when the expression is evaluated.evaluator - 式が評価されるときに実行される関数。
Example:
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")'));
// this will print: hello
|
In addition to the custom function arguments, the evaluator is passed an
arguments
variable as its first argument, which is equal to the second
argument of evaluate()
(e.g. the "values" when evaluating an expression).
Using Expression Providers ¶
When you use the ExpressionLanguage
class in your library, you often want
to add custom functions. To do so, you can create a new expression provider by
creating a class that implements
ExpressionFunctionProviderInterface.
This interface requires one method: getFunctions(), which returns an array of expression functions (instances of ExpressionFunction) to register:
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
To create an expression function from a PHP function with the fromPhp() static method:
1 |
ExpressionFunction::fromPhp('strtoupper');
|
Namespaced functions are supported, but they require a second argument to define the name of the expression:
1 |
ExpressionFunction::fromPhp('My\strtoupper', 'my_strtoupper');
|
You can register providers using registerProvider() or by using the second argument of the constructor:
1 2 3 4 5 6 7 8 9 10 |
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
// using the constructor
$expressionLanguage = new ExpressionLanguage(null, [
new StringExpressionLanguageProvider(),
// ...
]);
// using registerProvider()
$expressionLanguage->registerProvider(new StringExpressionLanguageProvider());
|
Tip
It is recommended to create your own ExpressionLanguage
class in your
library. Now you can add the extension by overriding the constructor:
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 $cache = null, array $providers = [])
{
// prepends the default provider to let users override it
array_unshift($providers, new StringExpressionLanguageProvider());
parent::__construct($cache, $providers);
}
}
|