查看PHP opcode擴(kuò)展模塊及Web服務(wù)
最近花了大約一星期的時(shí)間寫了一個(gè)PHP擴(kuò)展模塊Opdumer,并封裝成了Web服務(wù)(點(diǎn)擊這里訪問(wèn))。這個(gè)模塊的主要內(nèi)容是輸出PHP代碼對(duì)應(yīng)的opcode。其實(shí)之前已經(jīng)有一些用于查看opcode的擴(kuò)展模塊,如比較有名的vld。之所以重新實(shí)現(xiàn)一個(gè)這樣的模塊,主要是因?yàn)関ld不支持PHP_FUNCTION API,也就是說(shuō)vld只能用于CLI形式,而Opdumer同時(shí)擁有CLI API和PHP_FUNCTION API,另外,也想借助編寫這個(gè)模塊的機(jī)會(huì)學(xué)習(xí)Zend Engine中opcode的編譯和執(zhí)行機(jī)制。個(gè)人打算后面專門針對(duì)opcode的編譯執(zhí)行機(jī)制寫一篇文章,而本文主要描述Opcode的使用方法及對(duì)應(yīng)Web服務(wù)的使用。
Opdumper
安裝
Opdumper的源碼已經(jīng)托管在github上,其地址為:https://github.com/ericzhang-cn/opdumper??梢酝ㄟ^(guò)以下命令克隆源代碼:
- git clone https://github.com/ericzhang-cn/opdumper.git
Opdumper是一個(gè)標(biāo)準(zhǔn)的PHP Extension,安裝方法如下:
首先將Opdumper源碼放到PHP源碼包的ext/opdumper目錄下,進(jìn)入此目錄執(zhí)行如下命令:
- phpize
- ./configure
- make
- make install
然后在php.ini中添加一行配置:
- extension=opdumper.so
目前opdumper支持PHP>=5.3,在Linux和MacOS下測(cè)試通過(guò),Windows下未做測(cè)試。
CLI API
Opdumper支持類似vld的命令行方式輸出opcode,只需在執(zhí)行php命令時(shí)通過(guò)-d參數(shù)將opdumper.active=1傳入。例如我們有一個(gè)foo.php:
- <?php
- $a = 'hello';
- echo $a;
- ?>
執(zhí)行如下命令:
- php -d opdumper.active=1 foo.php
結(jié)果如下:
PHP_FUNCTION API
Opdumper還支持vld不支持的PHP_FUNCTION API,Opdumper提供了兩個(gè)PHP函數(shù):od_dump_opcodes_string和od_dump_opcodes_file。前者接受一個(gè)字符串作為產(chǎn)生,字符串是一段PHP代碼;后者接受一個(gè)PHP文件作為參數(shù),返回值均是一個(gè)存有opcode結(jié)果的PHP數(shù)組。以od_dump_opcodes_file為例,我們?cè)趂oo.php同一目錄下再寫一個(gè)bar.php:
- <?php
- $opcodes = od_dump_opcodes_file('./foo.php');
- var_dump($opcodes);
- ?>
執(zhí)行結(jié)果如下:
- array(3) {
- [0]=>
- array(8) {
- ["lineno"]=>
- int(2)
- ["opcode"]=>
- string(11) "ZEND_ASSIGN"
- ["op1_type"]=>
- string(2) "CV"
- ["op2_type"]=>
- string(5) "CONST"
- ["result_type"]=>
- string(0) ""
- ["op1"]=>
- string(2) "~0"
- ["op2"]=>
- string(5) "hello"
- ["result"]=>
- string(0) ""
- }
- [1]=>
- array(8) {
- ["lineno"]=>
- int(3)
- ["opcode"]=>
- string(9) "ZEND_ECHO"
- ["op1_type"]=>
- string(2) "CV"
- ["op2_type"]=>
- string(6) "UNUSED"
- ["result_type"]=>
- string(6) "UNUSED"
- ["op1"]=>
- string(2) "~0"
- ["op2"]=>
- string(6) "UNUSED"
- ["result"]=>
- string(6) "UNUSED"
- }
- [2]=>
- array(8) {
- ["lineno"]=>
- int(5)
- ["opcode"]=>
- string(11) "ZEND_RETURN"
- ["op1_type"]=>
- string(5) "CONST"
- ["op2_type"]=>
- string(6) "UNUSED"
- ["result_type"]=>
- string(6) "UNUSED"
- ["op1"]=>
- string(1) "1"
- ["op2"]=>
- string(6) "UNUSED"
- ["result"]=>
- string(6) "UNUSED"
- }
- }
Opdumper的Web服務(wù):Opcode Dumper
坦白說(shuō),安裝PHP模塊還是挺麻煩的。所以為了方便朋友們查看opcode,我為Opdumper搭建了一個(gè)在線Web服務(wù):http://supercompiler.com/app/opcode_dumper。
Web頁(yè)面訪問(wèn)
只要訪問(wèn)這個(gè)頁(yè)面,在編輯框中輸入或粘貼進(jìn)PHP代碼,就可以快速看到相應(yīng)的opcode:
同時(shí),也可以將結(jié)果下載到本地(CSV文件格式)。
HTTP API方式訪問(wèn)
您可以通過(guò)訪問(wèn)如下API獲取PHP代碼的opcode:
URI: http://supercompiler.com/api/dump_opcodes
Method: POST
Params: php_script=[您的PHP代碼]
返回值為JSON格式,成功時(shí)success字段為”true”,data字段存儲(chǔ)opcodes;失敗時(shí)success字段為”false”,msg字段存放失敗原因。
由于跨越的關(guān)系,目前只能使用Curl而不能使用Ajax方式調(diào)用這個(gè)API,后續(xù)會(huì)為其增加JSONP接口。
結(jié)語(yǔ)
目前這個(gè)模塊還比較初級(jí),有很多需要完善的地方。也歡迎有興趣的朋友通過(guò)github貢獻(xiàn)代碼。
原文鏈接:http://www.codinglabs.org/html/opdumper-and-web-opcode-dumper.html
【編輯推薦】