跳转到主要内容

什么是 PHP AST

AST(Abstract Syntax Tree,抽象语法树)是将源码分解为「具有语义结构」的树。 在你编写代码生成工具、静态分析工具、自动重构工具时,AST 几乎是必备基础。用字符串替换容易出错的转换,用 AST 就能按「function call」「class declaration」「use statement」等语法单元安全处理。

PHP 的内部 AST

PHP 7 以后的 Zend Engine 并不直接把 PHP 代码转换为 opcode,而是先转换为内部 AST 再编译。
  • php -r 执行的一行代码,内部也走完全相同的编译管线
  • OPcache 会缓存最终生成的 opcode 供复用
  • 在通常的应用开发中,几乎没有机会直接操作这份内部 AST
也就是说,当你想「用 AST 编辑代码」时,实用的做法不是操作 PHP 运行时内部 AST,而是使用用户态可用的 AST 库。

nikic/PHP-Parser 包

nikic/PHP-Parser 是将 PHP 代码解析、遍历、再生成为 AST 的标准库。README 与官方文档介绍的基本流程分为 3 步。

安装

基本解析示例(代码转 AST)

用 NodeVisitor 模式遍历、修改 AST

继承 NodeVisitorAbstract 后只需实现所需的钩子(enterNode / leaveNode)。复杂的转换建议在 enterNode 收集信息,在 leaveNode 做替换。

用 Pretty Printer 再生成代码

采用这套流程,你的转换对象就从「作为字符串的代码」变成了「作为语法树的代码」。

Laravel/Chisel 中的使用示例

laravel/chisel 是用于对 Starter Kit 做后处理裁剪的库。它在 composer.json 中依赖 nikic/php-parser 的 5.x 系列。 Chisel 中的 Laravel\Chisel\Ast\Source 按下列顺序进行 AST 编辑:
  1. ParserFactory::createForNewestSupportedVersion() 解析代码
  2. NodeTraverser 添加多个 Visitor(如 RemoveImportVisitor)执行转换
  3. PhpParser\PrettyPrinter\StandardprintFormatPreserving() 保留原格式回写
通过这种设计,use 语句、trait、interface 的移除都可以基于语法而非文本替换来安全执行。

用例

使用 AST 可以让以下开发更好推进:
  • 代码生成 CLI(生成模板后按语法级别编辑)
  • 静态分析工具(检测特定语法、发现违规)
  • 自动重构(API 迁移、命名调整的半自动化)
  • 项目模板的后处理(如 Chisel 的功能移除/替换)

小结

在一般的 Laravel 应用开发中,PHP AST 并非日常都会用到的功能。 不过,若你要做工具或包开发,AST 会成为实现「不易出错、可复现代码变更」的强大基础。先用 nikic/php-parser 的 Parser、Visitor、Pretty Printer 三件套在一个小型 CLI 上尝试即可。
最后修改于 2026年7月18日