ExpressionLanguage组件
编辑该页面ExpressionLanguage组件
ExpressionLanguage组件提供了一个引擎,这个引擎可以编译和评估表达式。一个表达式是一个一行程序,返回一个值(通常,但不限于,布尔值)。
安装
1
美元作曲家需要symfony /表达式ob娱乐下载语言
请注意
如果你安装这个组件之外的Symfony应用程序,你必须要求ob娱乐下载供应商/ autoload.php
文件在你的代码,使作曲家提供的类加载机制。读这篇文章为更多的细节。
表达式引擎怎么能帮助我吗?
组件的目的是允许用户使用更复杂的逻辑表达式内部配置。对于一些例子,Symfony框架使用表达式在安ob娱乐下载全、验证规则和路线匹配。
除了使用组件框架本身,ExpressionLanguage组件是一个完美的候选人的基础业务规则引擎。这个想法是为了让一个网站的站长配置在一个动态的方式不使用PHP和不引入安全问题:
1 2 3 4 5 6 7 8
#获取特价如果user.getGroup () (“good_customers”、“合作者”)# article.commentCount时促进文章首页> 100条。类别不(misc”) #产品时发送警报。股票< 15
表达式可以被视为一个非常限制PHP沙箱和不受外部注入您必须显式地声明的变量在一个表达式。
使用
ExpressionLanguage组件可以编译和评估表达式。经常返回一个布尔表达式是一行程序,可以使用代码执行的表达式如果
声明。一个表达式的一个简单的例子1 + 2
。您还可以使用更复杂的表达式,如someArray [3] .someMethod(酒吧)
。
组件提供了两种方法来处理表达式:
- 评价:没有被编译PHP计算表达式;
- 编译:表达式编译PHP,所以它可以缓存和评估。
组件的主类ExpressionLanguage:
1 2 3 4 5 6 7
使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage;美元expressionLanguage=新ExpressionLanguage ();var_dump (美元expressionLanguage- >评估(“1 + 2”));/ /显示3var_dump (美元expressionLanguage- >编译(“1 + 2”));/ /显示(1 + 2)
表达式语法
ExpressionLanguage组件使用一个特定的语法基于树枝的表达式语法。在本文档中,可以找到所有支持的语法。
支持文字
该组件支持:
- 字符串——单引号和双引号(例如。
“你好”
) - 数字——如。
103年
- 数组——使用类json符号(如。
[1,2]
) - 散列——使用类json符号(如。
{foo: '酒吧'}
) - 布尔值- - - - - -
真正的
和假
- 零- - - - - -
零
- 指数-也被称为科学(如。
1.99 e + 3
或1)依照
)
谨慎
一个反斜杠(\
)必须由4个反斜杠转义(
)在一个字符串和8反斜杠(
在正则表达式):
1 2
回声美元expressionLanguage- >评估(’“\ \ \ \”);/ /打印\美元expressionLanguage- >评估(“a \ \ \ \”匹配“/ ^ \ \ \ \ \ \ \ \ b /美元”的);/ /返回true
控制字符(如。\ n
)表达式替换为空格。为了避免这种情况,用一个反斜杠转义序列(如。\ \ n
)。
处理对象
当对象传递到一个表达式,可以使用不同的语法来访问属性和调用对象上的方法。
访问公共属性
可以通过使用访问对象的公共属性。
语法类似于JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
类苹果{公共美元各种;}美元苹果=新苹果();美元苹果- >各种=“密脆”;var_dump (美元expressionLanguage- >评估(“fruit.variety”,(“水果”= >美元苹果)));
这将打印出密脆
。
调用方法
的。
语法也可以用来调用对象上的方法,类似于JavaScript:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
类机器人{公共函数sayHi(美元次){美元问候= [];为(美元我=0;美元我<美元次;美元我+ +){美元问候[]=“嗨”;}返回内爆(' ',美元问候)。“!”;}}美元机器人=新机器人();var_dump (美元expressionLanguage- >评估(“robot.sayHi (3)”,(“机器人”= >美元机器人)));
这将打印出嗨嗨嗨!
。
处理函数
您还可以使用注册函数表达式中使用相同的语法PHP和JavaScript。ExpressionLanguage组件有一个函数的默认值:常数()
PHP,这将返回的值不变:
1 2 3 4 5
定义(“DB_USER”,“根”);var_dump (美元expressionLanguage- >评估(“常数(“DB_USER”)”));
这将打印出根
。
提示
阅读如何注册你自己的函数表达式中使用,请参阅“ExpressionLanguage组件”。
使用数组
如果你通过一个数组一个表达式,使用[]
类似于JavaScript语法来访问数组键:
1 2 3 4 5 6 7 8
美元数据= (“生活”= >10,“宇宙”= >10,“一切”= >22];var_dump (美元expressionLanguage- >评估(的数据(“生命”)(“宇宙”)+数据+数据(“一切”),(“数据”= >美元数据)));
这将打印出42
。
支持运营商
该组件有很多运营商:
算术运算符
+
(添加)- - - - - -
(减法)*
(乘法)/
(部门)%
(模量)* *
(战俘)
例如:
1 2 3 4 5 6 7 8
var_dump (美元expressionLanguage- >评估(“宇宙生命+ +一切”,(“生活”= >10,“宇宙”= >10,“一切”= >22)));
这将打印出42
。
按位运算符
&
(和)|
(或)^
(xor)
比较运算符
= =
(等于)= = =
(相同)! =
(不等于)= = !
(不一样的)<
(小于)>
(大于)< =
(小于或等于)> =
(大于或等于)匹配
(正则表达式匹配)
提示
为了测试一个字符串不匹配正则表达式,使用逻辑不
运营商结合匹配
接线员:
1
美元expressionLanguage- >评估(不(" foo "匹配" /酒吧/ ")”);/ /返回true
您必须使用括号,因为一元运算符不
在二元运算符优先级匹配
。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
美元ret1=美元expressionLanguage- >评估(“生活= =一切”,(“生活”= >10,“一切”= >22]);美元ret2=美元expressionLanguage- >评估(“生命>一切”,(“生活”= >10,“一切”= >22]);
这两个变量将被设置为假
。
逻辑运算符
不
或!
和
或& &
或
或| |
例如:
1 2 3 4 5 6 7 8
美元受潮湿腐烂=美元expressionLanguage- >评估(“宇宙<生命或生活<一切”,(“生活”= >10,“宇宙”= >10,“一切”= >22]);
这美元受潮湿腐烂
变量将被设置真正的
。
字符串运算符
~
(连接)
例如:
1 2 3 4 5 6 7
var_dump (美元expressionLanguage- >评估(“姓~ " ~名”,(“firstName”= >“亚瑟”,“姓”= >“削弱”)));
这将打印出亚瑟削弱
。
数组运算符
在
(包含)不是在
(不包含)
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
类用户{公共美元集团;}美元用户=新用户();美元用户- >组=“human_resources”;美元派系=美元expressionLanguage- >评估(的用户。集团在("human_resources", "marketing"]',(“用户”= >美元用户]);
的美元的派系
将评估真正的
。
数字运算符
。。
(范围)
例如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14
类用户{公共美元年龄;}美元用户=新用户();美元用户- >年龄=34;美元expressionLanguage- >评估(的用户。年龄在18。。45',(“用户”= >美元用户]);
这将评估真正的
,因为user.age
在从吗18
来45
。
三元运算符
foo吗?“是的”:“不”
foo ?:“不”
(等于foo吗?喷火:“不”
)foo吗?“是的”
(等于foo吗?“是”:“
)
传递变量
还可以通过变量的表达式,它可以是任何有效的PHP类型(包括对象):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage;美元expressionLanguage=新ExpressionLanguage ();类苹果{公共美元各种;}美元苹果=新苹果();美元苹果- >各种=“密脆”;var_dump (美元expressionLanguage- >评估(“fruit.variety”,(“水果”= >美元苹果)));/ /显示“密脆”
当使用该组件在一个Symfony应用程序中,某些对象和变量自动注入Syob娱乐下载mfony,这样你就可以在表达式中使用它们(例如请求,当前用户,等等):
谨慎
当使用变量表达式,避免将不可信数据的数组变量。如果无法避免,sanitize非字母数字的字符不可信的数据,以防止恶意用户注入控制字符和改变表达式。
缓存
ExpressionLanguage组件提供了一个编译()方法能够在纯PHP缓存表达式。但在内部,组件还缓存解析表达式,所以复制表达式可以被编译/评估更快。
工作流
这两个evaluate ()和编译()
前需要做的一些事情可以提供返回值。为evaluate ()
,这个开销更大。
这两种方法都需要标记和解析表达式。这是做的parse ()方法。它返回一个ParsedExpression。现在,编译()
方法只是返回该对象的字符串转换。的evaluate ()
方法需要遍历表达式的“节点”(部分保存在ParsedExpression
)和评估他们。
为了节省时间,ExpressionLanguage
缓存ParsedExpression
所以它可以跳过的标记和解析步骤重复表达。缓存是通过PSR-6CacheItemPoolInterface实例(在默认情况下,它使用一个ArrayAdapter)。您可以通过创建一个自定义定制这个缓存池或使用一个可用的和注射使用构造函数:
1 2 3 4 5
使用ob娱乐下载\组件\缓存\适配器\RedisAdapter;使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage;美元缓存=新RedisAdapter (…);美元expressionLanguage=新ExpressionLanguage (美元缓存);
另请参阅
看到缓存组件欧宝官网下载app文档了解更多信息可用缓存适配器。
使用解析和序列化的表达式
这两个evaluate ()
和编译()
可以处理ParsedExpression
和SerializedParsedExpression
:
1 2 3 4 5 6
/ /……/ /解析()方法返回一个ParsedExpression美元表达式=美元expressionLanguage- >解析(“1 + 4”[]);var_dump (美元expressionLanguage- >评估(美元表达式));/ /打印5
1 2 3 4 5 6 7 8 9
使用ob娱乐下载\组件\ExpressionLanguage\SerializedParsedExpression;/ /……美元表达式=新SerializedParsedExpression (“1 + 4”序列化(美元expressionLanguage- >解析(“1 + 4”[])- >getNodes ()));var_dump (美元expressionLanguage- >评估(美元表达式));/ /打印5
AST倾销和编辑
很难操作或检查表达式用ExpressionLanguage创建的组件,因为字符串表达式是平原。更好的方法是将这些表达式转换成一个AST。在计算机科学中,AST(抽象语法树)是“树表示的结构编程语言编写的源代码”。在Syob娱乐下载mfony中,ExpressionLanguage AST包含PHP类是一组节点代表给定的表达式。
倾销AST
调用getNodes ()方法解析任何表达式得到AST后:
1 2 3 4 5 6 7 8 9 10 11 12
使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage;美元ast= (新ExpressionLanguage ())- >解析(“1 + 2”[])- >getNodes ();/ /转储AST节点进行检查var_dump (美元ast);/ /转储AST节点作为一个字符串表示美元astAsString=美元ast- >dump ();
操纵AST
AST的节点也可以扔进一个PHP数组节点允许操纵他们。调用toArray ()方法将AST变成一个数组:
1 2 3 4 5 6 7
/ /……美元astAsArray= (新ExpressionLanguage ())- >解析(“1 + 2”[])- >getNodes ()- >toArray ();
扩展ExpressionLanguage
ExpressionLanguage可以扩展通过添加自定义功能。例如,在Symfony框架,安全检查用户的ob娱乐下载角色定制函数。
请注意
如果你想学习如何使用函数表达式中,读作“ExpressionLanguage组件”。
注册功能
在每个特定的注册功能ExpressionLanguage
实例。这意味着函数可以用于任何表达式执行的实例。
注册一个函数,使用注册()。这种方法有三个参数:
- 的名字一个表达式的函数的名称;
- 编译器——一个函数时执行编译使用的函数表达式;
- 评估者——一个函数时执行表达式进行求值。
例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage;美元expressionLanguage=新ExpressionLanguage ();美元expressionLanguage- >注册(“小写”,函数(美元str){返回sprintf (”(is_string (% 1 $ s) ?函数(% 1 $ s): % 1 $ s) ',美元str);},函数(美元参数,美元str){如果(! is_string (美元str)){返回美元str;}返回函数美元str);});var_dump (美元expressionLanguage- >评估(“小写(“HELLO”)”));/ /这将打印:你好
除了自定义函数参数,评估者是通过了参数
变量作为它的第一个参数,等于第二个参数evaluate ()
(如“价值观”在评估一个表达式)。
使用表达式提供者
当你使用ExpressionLanguage
类库,你经常要添加自定义功能。为此,您可以创建一个新的表达式提供者通过创建一个类实现ExpressionFunctionProviderInterface。
这个接口需要一个方法:getFunctions ()返回一个数组的表达功能的实例ExpressionFunction)注册:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
使用ob娱乐下载\组件\ExpressionLanguage\ExpressionFunction;使用ob娱乐下载\组件\ExpressionLanguage\ExpressionFunctionProviderInterface;类StringExpressionLanguageProvider实现了ExpressionFunctionProviderInterface{公共函数getFunctions(){返回(新ExpressionFunction (“小写”,函数(美元str){返回sprintf (”(is_string (% 1 $ s) ?函数(% 1 $ s): % 1 $ s) ',美元str);},函数(美元参数,美元str){如果(! is_string (美元str)){返回美元str;}返回函数美元str);}));}}
提示
创建一个函数从一个PHP函数的表达式fromPhp ()静态方法:
1
ExpressionFunction::fromPhp (“strtoupper”);
名称空间支持功能,但他们要求第二个参数定义表达式的名称:
1
ExpressionFunction::fromPhp (“我的\ strtoupper”,“my_strtoupper”);
你可以注册供应商使用registerProvider ()或使用构造函数的第二个参数:
1 2 3 4 5 6 7 8 9 10
使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage;/ /使用构造函数美元expressionLanguage=新ExpressionLanguage (零,(新StringExpressionLanguageProvider (),/ /……]);/ /使用registerProvider ()美元expressionLanguage- >registerProvider (新StringExpressionLanguageProvider ());
提示
建议创建你自己的ExpressionLanguage
类库。现在你可以添加扩展通过重写构造函数:
1 2 3 4 5 6 7 8 9 10 11 12 13
使用Psr\缓存\CacheItemPoolInterface;使用ob娱乐下载\组件\ExpressionLanguage\ExpressionLanguage作为BaseExpressionLanguage;类ExpressionLanguage扩展BaseExpressionLanguage{公共函数__construct(CacheItemPoolInterface美元缓存= null,数组美元供应商= []){/ /默认加提供者允许用户覆盖它函数美元供应商,新StringExpressionLanguageProvider ());父::__construct (美元缓存,美元供应商);}}