Twig 内部机制
原文:Twig Internals 翻译:小虾米(QQ:509129)
Twig 内部机制
Twig是非常可扩展的,您可以轻松攻击它。请记住,您应该尝试在黑客攻击核心之前创建扩展,因为大多数特性和增强都可以通过扩展来处理。这一章也对那些想了解Twig如何在引擎盖下工作的人有用。
Twig是如何工作的呢?
Twig模板的呈现可以概括为四个关键步骤:
加载模板:如果模板已经编译,加载它并进入评估步骤,否则:
首先,lexer将模板源代码标记为小块,以便进行更简单的处理;
然后,解析器将令牌流转换为有意义的节点树(抽象语法树);
最终,编译器将AST转换为PHP代码。
评估模板:它基本上意味着调用已编译模板的display()方法并将其传递给上下文。
Lexer
lexer将模板源代码标记为令牌流(每个令牌是Twig_Token的一个实例,而流是Twig_TokenStream的实例)。默认的lexer识别13种不同的标记类型:
Twig_Token::BLOCK_START_TYPE,Twig_Token::BLOCK_END_TYPE:块的分隔符({ % % })
Twig_Token::VAR_START_TYPE,Twig_Token::VAR_END_TYPE:变量的分隔符({ } })
Twig_Token::TEXT_TYPE:表达式外的文本;
Twig_Token:NAME_TYPE:表达式中的名称;
Twig_Token::NUMBER_TYPE:一个表达式中的数字;
Twig_Token::STRING_TYPE:表达式中的字符串;
Twig_Token::OPERATOR_TYPE:操作员;
Twig_Token::PUNCTUATION_TYPE:标点符号;
Twig_Token::插值_start_type,Twig_Token::插值函数:字符串插值的分隔符;
Twig_Token::EOF_TYPE:结束的模板。
您可以通过调用环境的tokenize()方法手动将源代码转换为令牌流。
由于流有一个__toString()方法,因此可以通过与对象相呼应来对它进行文本表示:
这里是Hello { { name }模板的输出:
可以通过调用setLexer()方法来更改默认的lexer(Twig_Lexer):
解析器(Parser)
解析器将令牌流转换为AST(抽象语法树)或节点树(Twig_Node_Module的实例)。核心扩展定义了基本的节点,例如:for,如果,…表达式节点。
通过调用环境的parse()方法,您可以手动将标记流转换为节点树:
与节点对象相呼应,可以得到树的良好表示:
这里是Hello { { name }模板的输出:
默认解析器(Twig_TokenParser)可以通过调用setParser()方法来更改:
编译器(Compiler)
最后一步是由编译器完成的。它将节点树作为输入,并生成用于模板运行时执行的PHP代码。
您可以通过一个环境的compile()方法手工地将节点树编译为PHP代码:
Hello { { name }模板的生成模板如下(根据所使用的Twig版本,实际的输出会有所不同):
默认编译器(Twig_Compiler)可以通过调用setCompiler()方法来更改:
Last updated