WARNING: You are browsing the documentation for Symfony 2.4 which is not maintained anymore. Consider upgrading your projects to Symfony 4.0.

Extending the ExpressionLanguage

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 "Working with Functions".

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;
  • compiler - A function executed when compiling an expression using the function;
  • evaluator - A function executed when the expression is evaluated.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;

$language = new ExpressionLanguage();
$language->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);
});

echo $language->evaluate('lowercase("HELLO")');

This will print hello. Both the compiler and evaluator are passed an arguments variable as their first argument, which is equal to the second argument to evaluate() or compile() (e.g. the "values" when evaluating or the "names" if compiling).

Creating a new ExpressionLanguage Class

When you use the ExpressionLanguage class in your library, it's recommend to create a new ExpressionLanguage class and register the functions there. Override registerFunctions to add your own functions:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
namespace Acme\AwesomeLib\ExpressionLanguage;

use Symfony\Component\ExpressionLanguage\ExpressionLanguage as BaseExpressionLanguage;

class ExpressionLanguage extends BaseExpressionLanguage
{
    protected function registerFunctions()
    {
        parent::registerFunctions(); // do not forget to also register core functions

        $this->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);
        });
    }
}

This work, including the code samples, is licensed under a Creative Commons BY-SA 3.0 license.