使用解析器缓存来缓存表达式

3.4 版本
维护中的版本

ExpressionLanguage组件已经提供了 compile() 方法来把表达式缓存为原生PHP。但是在内部,该组件同时缓存了解析过的表达式(parsed expressions),所以重复的表达式可以被更快速地编译/求值(evaluated)。

工作流 

evaluate()compile() 两个方法都要在返回value之前做些什么事情。对于 evaluate()来说,开销更大一些。

两个方法要对表达式进行tokenize和解析。这可以被 parse() 方法完成。它返回一个 ParsedExpression。现在, compile() 只返回这个对象的字符串变体。evaluate() 方法需要遍历 "节点" (nodes。即,一个存储在 ParsedExpression 中的表达式片断),然后迅即对求值。

为了节省时间, the ExpressionLanguage 缓存了 ParsedExpression 以便它能跳过对重复的表达式的tokenize和解析的步骤。缓存是由 ParserCacheInterface 实例完成的 (默认时,它使用了一个 ArrayParserCache)。你可以通过创建一个自定义的 ParserCache 来定制这一步,然后使用构造器注入把它注入到对象中:

1
2
3
4
5
use Symfony\Component\ExpressionLanguage\ExpressionLanguage;
use Acme\ExpressionLanguage\ParserCache\MyDatabaseParserCache;
 
$cache = new MyDatabaseParserCache(...);
$language = new ExpressionLanguage($cache);

DoctrineBridge 使用 doctrine缓存库 进而实现了一个Parser Cache的实现,令你能够使用全部类型的缓存策略进行缓存。比如Apc, Filesystem以及Memcached等。

使用经过解析和序列化的表达式 

evaluate()compile() 方法都可以处理 ParsedExpression实例 和 SerializedParsedExpression 实例:

1
2
3
4
5
6
7
// ...
 
// the parse() method returns a ParsedExpression
// parse()方法返回一个ParsedExpress
$expression = $language->parse('1 + 4', array());
 
var_dump($language->evaluate($expression)); // prints 5 / 输出5
1
2
3
4
5
6
7
8
9
use Symfony\Component\ExpressionLanguage\SerializedParsedExpression;
// ...
 
$expression = new SerializedParsedExpression(
    '1 + 4',
    serialize($language->parse('1 + 4', array())->getNodes())
);
 
var_dump($language->evaluate($expression)); // prints 5 / 输出5

本文,包括例程代码在内,采用的是 Creative Commons BY-SA 3.0 创作共用授权。

登录symfonychina 发表评论或留下问题(我们会尽量回复)