Skip to content

Commit e9a81bf

Browse files
committed
[symfony#3044] Furthering @wouterj's work on the ExpressionLanguage component
This adds more examples, details about how to pass in variables, and working with objects/arrays
1 parent 70b475b commit e9a81bf

File tree

2 files changed

+230
-20
lines changed

2 files changed

+230
-20
lines changed

Diff for: components/expression_language/introduction.rst

+62-7
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,51 @@ The ExpressionLanguage Component
1010
(mostly, but not limited to, Booleans).
1111

1212
.. versionadded:: 2.4
13-
The ExpressionLanguage component was new in Symfony 2.4.
13+
The ExpressionLanguage component was added in Symfony 2.4.
1414

1515
Installation
1616
------------
1717

1818
You can install the component in 2 different ways:
1919

20-
* Use the official Git repository (https://github.com/symfony/expression-language);
2120
* :doc:`Install it via Composer </components/using_components>` (``symfony/expression-language`` on `Packagist`_).
21+
* Use the official Git repository (https://github.com/symfony/expression-language);
22+
23+
How can the Expression Engine Help Me?
24+
--------------------------------------
25+
26+
The purpose of the component is to allow users to use expressions inside
27+
configuration for more complex logic. In the Symfony2 Framework, for example,
28+
expressions can be used in security, for validation rules, and in route matching.
29+
30+
Besides using the component in the framework itself, the ExpressionLanguage
31+
component is a perfect candidate for the foundation of a *business rule engine*.
32+
The idea is to let the webmaster of a website configure things in a dynamic
33+
way without using PHP and without introducing security problems:
34+
35+
.. code-block:: text
36+
37+
# Get the special price if
38+
user.getGroup() in ['good_customers', 'collaborator']
39+
40+
# Promote article to the homepage when
41+
article.commentCount > 100 and article.category not in ["misc"]
42+
43+
# Send an alert when
44+
product.stock < 15
45+
46+
Expressions can be seen as a very restricted PHP sandbox and are immune to
47+
external injections as you must explicitly declare which variables are available
48+
in an expression.
2249

2350
Usage
2451
-----
2552

2653
The ExpressionLanguage component can compile and evaluate expressions.
27-
Expressions are one-liners which most of the time return a boolean, you can
28-
compare them to the expression in an ``if`` statement. A simple example of an
29-
expression is ``1 + 2``. You can also use more complicated expressions, such
30-
as ``someArray[3].someMethod('bar')``.
54+
Expressions are one-liners that often return a Boolean, which can be used
55+
by the code executing the expression in an ``if`` statements. A simple example
56+
of an expression is ``1 + 2``. You can also use more complicated expressions,
57+
such as ``someArray[3].someMethod('bar')``.
3158

3259
The component provides 2 ways to work with expressions:
3360

@@ -49,7 +76,35 @@ The main class of the component is
4976
Expression Syntax
5077
-----------------
5178

52-
See ":doc:`/components/expression_language/syntax`" to learn the syntax of the
79+
See :doc:`/components/expression_language/syntax` to learn the syntax of the
5380
ExpressionLanguage component.
5481

82+
Passing in Variables
83+
--------------------
84+
85+
You can also pass variables into the expression, which can be of any valid
86+
PHP type (including objects)::
87+
88+
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
89+
90+
$language = new ExpressionLanguage();
91+
92+
class Apple
93+
{
94+
public $variety;
95+
}
96+
97+
$apple = new Apple();
98+
$apple->variety = 'Honeycrisp';
99+
100+
echo $language->evaluate(
101+
'fruit.variety',
102+
array(
103+
'fruit' => $apple,
104+
)
105+
);
106+
107+
This will print "Honeycrisp". For more information, see the :doc:`/components/expression_language/syntax`
108+
entry, especially :ref:`component-expression-objects` and :ref:`component-expression-arrays`.
109+
55110
.. _Packagist: https://packagist.org/packages/symfony/expression-language

Diff for: components/expression_language/syntax.rst

+168-13
Original file line numberDiff line numberDiff line change
@@ -9,24 +9,102 @@ expression syntax of Twig. In this document, you can find all supported
99
syntaxes.
1010

1111
Supported Literals
12-
~~~~~~~~~~~~~~~~~~
12+
------------------
1313

1414
The component supports:
1515

1616
* **strings** - single and double quotes (e.g. ``'hello'``)
1717
* **numbers** - e.g. ``103``
18-
* **arrays** - using twig notation (e.g. ``[1, 2]``)
19-
* **hashes** - using twig notation (e.g. ``{ foo: 'bar' }``)
18+
* **arrays** - using JSON-like notation (e.g. ``[1, 2]``)
19+
* **hashes** - using JSON-like notation (e.g. ``{ foo: 'bar' }``)
2020
* **booleans** - ``true`` and ``false``
2121
* **null** - ``null``
2222

23+
.. _component-expression-objects:
24+
25+
Working with Objects
26+
--------------------
27+
28+
When passing objects into an expression, you can use different syntaxes to
29+
access properties and call methods on the object.
30+
31+
Accessing Public Methods
32+
~~~~~~~~~~~~~~~~~~~~~~~~
33+
34+
Public properties on objects can be accessed by using the ``.`` syntax, similar
35+
to JavaScript::
36+
37+
class Apple
38+
{
39+
public $variety;
40+
}
41+
42+
$apple = new Apple();
43+
$apple->variety = 'Honeycrisp';
44+
45+
echo $language->evaluate(
46+
'fruit.variety',
47+
array(
48+
'fruit' => $apple,
49+
)
50+
);
51+
52+
Calling Methods
53+
~~~~~~~~~~~~~~~
54+
55+
The ``.`` syntax can also be used to call methods on an object, similar to
56+
JavaScript::
57+
58+
class Robot
59+
{
60+
public function sayHi($times)
61+
{
62+
$greetings = array();
63+
for ($i = 0; $i < $times; $i++) {
64+
$greetings[] = 'Hi';
65+
}
66+
67+
return implode(' ', $greetings).'!';
68+
}
69+
}
70+
71+
$robot = new Robot();
72+
73+
echo $language->evaluate(
74+
'robot.sayHi(3)',
75+
array(
76+
'robot' => $robot,
77+
)
78+
);
79+
80+
This will print "Hi Hi Hi!";
81+
82+
.. _component-expression-arrays:
83+
84+
Working with Arrays
85+
-------------------
86+
87+
If you pass an array into an expression, use the ``[]`` syntax to access
88+
array keys, similar to JavaScript::
89+
90+
$data = array('life' => 10, 'universe' => 10, 'everything' => 22);
91+
92+
echo $language->evaluate(
93+
'data["life"] + data["universe"] + data["everything"]',
94+
array(
95+
'data' => $data,
96+
)
97+
);
98+
99+
This will print ``42``.
100+
23101
Supported Operators
24-
~~~~~~~~~~~~~~~~~~~
102+
-------------------
25103

26104
The component comes with a lot of operators:
27105

28106
Arithmetic Operators
29-
....................
107+
~~~~~~~~~~~~~~~~~~~~
30108

31109
* ``+`` (addition)
32110
* ``-`` (subtraction)
@@ -35,20 +113,33 @@ Arithmetic Operators
35113
* ``%`` (modulus)
36114
* ``**`` (pow)
37115

116+
For example::
117+
118+
echo $language->evaluate(
119+
'life + universe + everything',
120+
array(
121+
'life' => 10,
122+
'universe' => 10,
123+
'everything' => 22,
124+
)
125+
);
126+
127+
This will print out ``42``.
128+
38129
Assignment Operators
39-
....................
130+
~~~~~~~~~~~~~~~~~~~~
40131

41132
* ``=``
42133

43134
Bitwise Operators
44-
.................
135+
~~~~~~~~~~~~~~~~~
45136

46137
* ``&`` (and)
47138
* ``|`` (or)
48139
* ``^`` (xor)
49140

50141
Comparison Operators
51-
....................
142+
~~~~~~~~~~~~~~~~~~~~
52143

53144
* ``==`` (equal)
54145
* ``===`` (identical)
@@ -67,31 +158,95 @@ Comparison Operators
67158

68159
$language->evaluate('not "foo" matches "/bar/"'); // returns true
69160

161+
Examples::
162+
163+
$ret1 = $language->evaluate(
164+
'life == everything',
165+
array(
166+
'life' => 10,
167+
'universe' => 10,
168+
'everything' => 22,
169+
)
170+
);
171+
172+
$ret2 = $language->evaluate(
173+
'life > everything',
174+
array(
175+
'life' => 10,
176+
'universe' => 10,
177+
'everything' => 22,
178+
)
179+
);
180+
181+
These would both return ``false``.
182+
70183
Logical Operators
71-
.................
184+
~~~~~~~~~~~~~~~~~
72185

73186
* ``not`` or ``!``
74187
* ``and`` or ``&&``
75188
* ``or`` or ``||``
76189

190+
For example::
191+
192+
$ret = $language->evaluate(
193+
'life < universe or life < everything',
194+
array(
195+
'life' => 10,
196+
'universe' => 10,
197+
'everything' => 22,
198+
)
199+
);
200+
201+
This would return ``true``.
202+
77203
String Operators
78-
................
204+
~~~~~~~~~~~~~~~~
79205

80206
* ``~`` (concatenation)
81207

208+
For example::
209+
210+
$ret4 = $language->evaluate(
211+
'firstName~" "~lastName',
212+
array(
213+
'firstName' => 'Arthur',
214+
'lastName' => 'Dent',
215+
)
216+
);
217+
218+
This would print out ``Arthur Dent``.
219+
82220
Array Operators
83-
...............
221+
~~~~~~~~~~~~~~~
84222

85223
* ``in`` (contain)
86224
* ``not in`` (does not contain)
87225

226+
For example::
227+
228+
class User
229+
{
230+
public $group;
231+
}
232+
233+
$user = new User();
234+
$user->group = 'human_resources';
235+
236+
$ret5 = $language->evaluate(
237+
'user.group in ["human_resources", "marketing"]',
238+
array(
239+
'user' => $user
240+
)
241+
);
242+
88243
Numeric Operators
89-
.................
244+
~~~~~~~~~~~~~~~~~
90245

91246
* ``..`` (range)
92247

93248
Ternary Operators
94-
.................
249+
~~~~~~~~~~~~~~~~~
95250

96251
* ``foo ? 'yes' : 'no'``
97252
* ``foo ?: 'no'`` (equal to ``foo ? foo : 'no'``)

0 commit comments

Comments
 (0)