Opcode(操作碼) 是 PHP 腳本經編譯器編譯後產生的中間語言,類似 Java 的 Bytecode 或 .NET 的 MSIL。Zend Engine 執行 PHP 程式碼需經歷四個階段:
<?php
echo "Hello World";
$a = 1 + 1;
echo $a;
?>
使用 token_get_all() 可見掃描結果:每個關鍵字、運算子、字串、空白都會轉為 [Token ID, 原始內容] 陣列,例如 T_ECHO、T_STRING、T_LNUMBER 等。
捨棄多餘空白,轉為簡單表達式:
每條 Opcode 包含五部分:Opcode編號、結果、運算元1、運算元2、擴展值。
ZEND_ECHO 'Hello World'
ZEND_ADD ~0 1 1
ZEND_ASSIGN !0 ~0
ZEND_ECHO !0
IS_TMP_VAR (~0):暫存變數,儲存中間結果IS_VAR ($var):一般變數IS_CV (!0):PHP 5.1+ 編譯器快取機制,直接指向變數記憶體位址,避免查找符號表範例中 $a 被優化為 !0 (IS_CV)。
預設每次請求都會完整跑完前三階段。APC (Alternative PHP Cache) 或 PHP 5.5+ 內建的 OPcache 可將編譯後的 Opcode 存入共享記憶體,後續請求直接跳過掃描、解析、編譯,直接執行,大幅提升吞吐量。
PHP 程式碼
↓ Scanning (Lexing)
Tokens (語言片段)
↓ Parsing (語法分析)
有意義的表達式
↓ Compilation (編譯)
Opcode (操作碼)
↓ Execution (執行)
程式輸出
opcache.memory_consumption、opcache.max_accelerated_files 等參數