Skip to main content

什麼是 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 編輯程式碼」時,實務上使用可在使用者空間操作的 AST 函式庫較為實用,而非 PHP 執行時內部 AST。

nikic/PHP-Parser 套件

nikic/PHP-Parser 是用於解析、走訪、再生 PHP 程式碼為 AST 的標準函式庫。README 與官方文件說明其基本步驟有下列 3 步。

安裝

基本 parse 範例(將程式碼轉為 AST)

以 NodeVisitor 模式走訪、變更 AST

繼承 NodeVisitorAbstract 後,只需實作所需的 hook(enterNode / leaveNode)。於複雜的變換中,於 enterNode 蒐集資訊、於 leaveNode 置換的流程頗為有效。

以 Pretty Printer 再生程式碼

透過此流程,可以將「作為語法樹的程式碼」而非「作為字串的程式碼」作為變換對象。

Laravel/Chisel 的使用範例

laravel/chisel 是於後處理階段裁剪啟動套件的函式庫。於 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 的功能刪除、置換)

總結

PHP AST 於一般 Laravel 應用程式開發並非每日使用的功能。 不過若您要推動工具開發或套件開發,AST 是實現「不易損壞且具再現性的程式碼變更」的強力基礎。首先請以小型 CLI 試用 nikic/php-parser 的 Parser、Visitor、Pretty Printer 三者。
最後修改於 2026年8月2日