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组件。
传递变量
还可以通过变量的表达式,它可以是任何有效的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
实例。这意味着函数可以用于任何表达式执行的实例。
注册一个函数,使用注册()。这种方法有三个参数:
- 的名字一个表达式的函数的名称;
- 编译器——一个函数时执行编译使用的函数表达式;
- 评估者——一个函数时执行表达式进行求值。
例子:
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 (美元缓存,美元供应商);}}