PHP-Parser是nikic用PHP编写的PHP5.2到PHP8.3解析器,其目的是简化静态代码剖析和操作。PHP Parser 是一个用于源代码解析的项目,值得一提的是它利用纯 PHP 编写,对付 PHP 程序员来说,能利用自己熟习的措辞来做静态剖析等源码处理,无疑是一大便利。
5.0.0 发布列表新增长加了PhpVersion 类,它在许多地方都被接管(例如ParserFactory,Parser,Lexer,PrettyPrinter),并对目标PHP版本进行更精确的掌握。添加了PHP8解析器,只管它与PHP 7解析器的差异仅在于连接优先级。添加了 Parser::getTokens() 方法。添加了一个 Modifiers 类,作为 Stmt\Class_::MODIFIER_ 的替代。添加了从 NodeVisitor::enterNode() 返回数组或 REMOVE_NODE 的支持。添加了许多额外的类型注释。PhpStan现在利用。为PHP-Fuzzer添加了一个模糊目标,这便是创造很多俊秀的打印机缺点的缘故原由。在Param上添加了isPromoted()、isPublic()、isProtected()、isPrivate()和isReadonly()方法。在trait builder中增加了对类常量的支持。添加了 PrettyPrinter 接口。添加了在切换静态修正器时对格式保留的支持。php-parse二进制文件现在接管-作为文件名,在这种情形下,它将从stdin读取。支持NodeVisitor::REPLACE_WITH_NULL。在俊秀的打印机中增加了对CRLF换行符的支持,利用新的newline选项。访问者现在可以直接通报给NodeTraverser布局函数。不再须要单独调用addVisitor()。在NodeDumper中添加了对打印附加属性(如kind)的支持。为InterpolatedStringPart和heredoc/nowdocString_s添加了rawValue属性,该属性供应原始的未解析值。它以前只适用于非插值的单引号/双引号字符串。添加了Stmt\Block以表示{}代码块。以前,这样的代码块被展平到父语句数组中。Stmt\Block不会为常日与代码块一起利用的构造创建,例如if ($x) { $y; }将如前所述表示,而if ($x) { { $x; } }将具有额外的Stmt\Block包装器。修正现在须要PHP 7.4来运行PHP-Parser。在可能的情形下添加了属性类型。标准俊秀打印机的屏幕已调度,以更紧密地匹配PSR-12。内部token表示现在利用PhpParser\Token类,它与PHP 8 token表示(PhpToken)兼容。数组解构现在总是利用Expr\List_节点表示,纵然它利用[]语法。重命名了许多节点类,并将不是真实的表达式/语句的内容移到了Expr/Stmt层次构造之外。保留了旧名称的兼容性。Pretty打印机不再无条件地将yield括在括号中,除非目标版本设置为早于PHP 7.0。Pretty打印机现在默认为PHP 7.4作为目标版本。打印else if { }而不是else { if { } }。访问者的leaveNode()方法现在以与enterNode()相反的顺序调用。将NodeTraverser::REMOVE_NODE等移至NodeVisitor::REMOVE_NODE。旧的常量仍旧可用,以便兼容。Name子节点parts已被name更换,它将名称存储为字符串,而不是由名称空间分隔符分隔的部分数组。getParts()方法返回旧的表示。不再接管Node布局函数中类型的字符串。相反,必须通报Identifier、Name或ComplexType。Comment::getReformattedText()现在将CRLF换行符规范化为LF换行符。Lexer不再接管选项。Lexer\Emulative只接管PhpVersion。startLexing()、getTokens()和handleHaltCompiler()方法已被删除。相反,只有一个方法tokenize()返回令牌。属性处理已从词法剖析器移到解析器,不再可配置。将始终添加comments、startLine、endLine、startTokenPos、endTokenPos、startFilePos和endFilePos属性。如果目标版本是>= 7.3(灵巧的heredoc/nowdoc),pretty打印机现在缩进heredoc/nowdoc字符串。利用访问者分配评论。这办理了将注释分配给共享起始位置的所有节点的长期问题。现在只有最外层的节点将保存注释。提高NodeDumper在大型转储中的性能。移除PHP 5解析器已被删除。PHP 7解析器已经由调度,可以更优雅地处理PHP 5代码。删除了不推举利用的Error布局函数,该布局函数采取行号而不是属性数组。Comment::getLine()、Comment::getTokenPos()和Comment::getFilePos()方法已被删除。利用Comment::getStartLine()、Comment::getStartTokenPos()和Comment::getStartFilePos()代替。删除Stmt\Throw_节点,利用Stmt\Expression内的Expr\Throw_代替。删除ParserFactory::create()。固定俊秀的打印机现在利用一个更准确的处理一元运算符优先级,如果须要,只会把它们括在括号里。这许可修复许多其他与优先级干系的bug。俊秀的打印机现在尊重clone,throw和箭头函数的优先级。修复了替代elseif/else语法的格式保留。修复了将字符串打印为heredoc/nowdoc以适应灵巧的文档字符串语义的安全性检讨。修复了文档字符串末端的\r可能被缺点地合并到CRLF序列中,后面是\n的各种情形。__halt_compiler不再被识别为半保留关键字,符合PHP行为。<?=不再被识别为半保留关键字。修复了对非常大的溢出\u转义序列的处理。在格式保留打印机中不修剪前导空格。根据目标PHP版本,在格式保留打印机中将DEL视为标具名符。改动了在没有明确指定缺点处理程序的情形下,在仿照lexer中报告缺点的问题。优雅地处理Differ中的非连续数组索引。弃用Node::getLine()方法已被弃用。利用Node::getStartLine()代替。大略利用对付以下一段 PHP 代码
<?phpecho 'Hi', '开源技能小栈';
编写解析文件
<?phprequire __DIR__ . '/../vendor/autoload.php';$code = <<<'CODE'<?phpecho 'Hi', '开源技能小栈';CODE;$parser = (new \PhpParser\ParserFactory())->createForNewestSupportedVersion();try { $ast = $parser->parse($code);} catch (\PhpParser\Error $error) { echo "Parse error: {$error->getMessage()}\n"; return;}$dumper = new \PhpParser\NodeDumper;echo $dumper->dump($ast) . "\n";
解析后天生的树构造如下
array( 0: Stmt_Echo( exprs: array( 0: Scalar_String( value: Hi ) 1: Scalar_String( value: 开源技能小栈 ) ) ))