diff --git a/components/expression_language/extending.rst b/components/expression_language/extending.rst new file mode 100644 index 00000000000..ddcc44d476f --- /dev/null +++ b/components/expression_language/extending.rst @@ -0,0 +1,87 @@ +.. index:: + single: Extending; ExpressionLanguage + +Extending the ExpressionLanguage +================================ + +The ExpressionLanguage can be extended by adding custom functions. For +instance, in the 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 + ":ref:`component-expression-functions`". + +Register Functions +------------------ + +Functions will be registered on the current ``ExpressionLanguage`` instance. +That means the functions can be used in any expression executed by that +instance. + +To register a function, use +:method:`Symfony\\Component\\ExpressionLanguage\\ExpressionLanguage::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. + +.. code-block:: php + + use Symfony\Component\ExpressionLanguage\ExpressionLanguage; + + $language = new ExpressionLanguage(); + $language->register('lowercase', function ($str) { + if (!is_string($str)) { + return $str; + } + + return sprintf('strtolower(%s)', $str); + }, function ($str) { + if (!is_string($str)) { + return $str; + } + + return strtolower($str); + }); + + echo $language->evaluate('lowercase("HELLO")'); + +This will print ``hello``. + +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. +The class will execute ``registerFunctions`` to register the default +functions, you can override this to also add your own functions:: + + 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) { + if (!is_string($str)) { + return $str; + } + + return sprintf('strtolower(%s)', $str); + }, function ($str) { + if (!is_string($str)) { + return $str; + } + + return strtolower($str); + }); + } + } diff --git a/components/expression_language/syntax.rst b/components/expression_language/syntax.rst index 3552cad5b7d..e105e82bdb8 100644 --- a/components/expression_language/syntax.rst +++ b/components/expression_language/syntax.rst @@ -81,6 +81,29 @@ JavaScript:: This will print ``Hi Hi Hi!``. +.. _component-expression-functions: + +Working with Functions +---------------------- + +You can also use registered functions in the expression by using the same +syntax as PHP and JavaScript. The ExpressionLanguage component comes with one +function by default: ``constant()`` Which will return the value of the PHP +constant:: + + define('DB_USER', 'root'); + + echo $language->evaluate( + 'constant("DB_USER")' + ); + +This will print ``root``. + +.. tip:: + + To read how to register your own function to use in an expression, see + ":doc:`/components/expression_language/extending`". + .. _component-expression-arrays: Working with Arrays @@ -128,11 +151,6 @@ For example:: This will print out ``42``. -Assignment Operators -~~~~~~~~~~~~~~~~~~~~ - -* ``=`` - Bitwise Operators ~~~~~~~~~~~~~~~~~ @@ -249,6 +267,26 @@ Numeric Operators * ``..`` (range) +For example:: + + class User + { + public $age; + } + + $user = new User(); + $user->age = 34; + + $language->evaluate( + 'user.age in 18..45', + array( + 'user' => $user, + ) + ); + +This will evaluate to ``true``, because ``user.age`` is in the range from +``18`` till ``45`` + Ternary Operators ~~~~~~~~~~~~~~~~~