php核心分析 opcode

2021-07-25 06:36:10 字數 3001 閱讀 5528

檢視opcode

php是先把原始碼解析成opcode,然後再把opcode傳遞給zend_vm進行執行的。

// 乙個opcode的結構

struct _zend_op ;

在php7中,我們能很方便用phpdbg來檢視乙個檔案或者乙個函式的opcode了。至於phpdbg的使用,現在網上介紹不多,不過好在有很詳細的help文件。下面是乙個最簡單的opcode**:

$ bin/phpdbg -f /home/xiaoju/software/php7/demo/echo.php

prompt> list

10000001: 00002:

00003: $a = 1;

00004: $b = $a;

00005: $b = $b + 1;

00006: echo $b;

00007:

prompt> print exec

[context /home/xiaoju/software/php7/demo/echo.php (6 ops)]

l1-7 () /home/xiaoju/software/php7/demo/echo.php - 0x7fe3fae63300 + 6 ops

l3 #0 assign $a 1

l4 #1 assign $b $a

l5 #2 add $b 1 ~2

l5 #3 assign $b ~2

l6 #4 echo $b

l7 #5 return 1

這個php檔案就做了乙個最簡單的加法操作。生成了6個_zend_op。所展示的每一行代表乙個_zend_op

_zendop.lineno  op號   _zend_op.opcode       _zend_op.op1          _zend_op.op2          _zend_op.result

l5 #2 add $b 1 ~2

這裡_zend_op.opcode對應的操作在官網有文件和詳細的例子可以檢視:

值得一說的是,phpdbg還有乙個遠端ui版本,能讓我們在近端診斷服務端的php資訊

gdb但是我們的目標還是在於研究php原始碼,phpdbg只能分析到opcode這層,還是不夠的,gdb可能是更好的選擇。

gdb的使用和平時使用差不多,比如我現在有個指令碼echo.php:

1 2

3 $a = 1;

4 $b = $a;

5 $b = $b + 1;

6echo $b;

我的php安裝路徑在:

/home/xiaoju/software/php7/bin/php
php原始碼路徑在:

/home/xiaoju/webroot/php-src/php-src-master/
執行gdb

$ gdb /home/xiaoju/software/php7/bin/php
載入gdbinit:

(gdb) source /home/xiaoju/webroot/php-src/php-src-master/.gdbinit
設定斷點:

(gdb) b zend_execute_scripts
執行:

(gdb) run -f /home/xiaoju/software/php7/demo/echo.php
我想在1459這行設定個斷點:

1452          for (i = 0; i < file_count; i++) 

1457

1458 op_array = zend_compile_file(file_handle, type);

1459 if (file_handle->opened_path)

(gdb) b 1459

繼續跑

(gdb) continue

(gdb) s

(gdb) s

列印出這個時候的op_array

(gdb) p *op_array

$4 = }

我可以優化輸出:

(gdb) set print pretty on

(gdb) p *op_array

$5 =

}

我想打出op_array.filename.val的具體值

(gdb) p (op_array.filename.len)

$12 = 40

(gdb) p *(op_array.filename.val)@40

$13 = "/home/xiaoju/software/php7/demo/echo.php"

好了,我們可以順便研究下_zend_op_array這個結構:

// opcode組成的陣列,編譯的時候就是生成這個結構

struct _zend_op_array ;

PHP編譯原理之Opcode

一.編譯原理的過程 編譯程式的工作過程一般可以劃分為五個階段 1 詞法分析 輸入源程式,對構成源程式的字串進行掃瞄和分解,識別出乙個個的單詞 如基本字 標識 符 常量 運算子 標點符 左右括號等 描述詞法規則通常用 正規式 和 有限自動機 依循的原則 詞法規則。線性分析。2 語法分析 在詞法分析的基...

PHP快取之Opcode快取

什麼是opcode快取?當直譯器完成對指令碼 的分析後,便將他們聲稱可以直接執行的中間 也成為操作碼 operate code,opcode opcode cache的目的是避免重複編譯,減少cpu和記憶體的開銷。但是一般動態 的效能瓶頸都在io操作以及資料庫操作,那麼opcode快取能夠帶來的優化...

PHP配置檔案快取opcode設定步驟

引言 安裝zendoptimizer或apc2.0等可以加速php 訪問,主要用於快取opcode而不是每次重複編譯,進而減少cpu和記憶體開銷 php5.5 後不需要安裝第三方軟體,直接開啟php配置檔案中opcache即可。步驟1 開啟php配置檔案 php.ini 輸入下屬 並 重啟apach...