国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 編程 > PHP > 正文

如何使用PHP Embed SAPI實現(xiàn)Opcodes查看器

2020-03-22 18:34:33
字體:
供稿:網(wǎng)友
PHP提供了一個Embed SAPI,也就是說,PHP容許你在C/C++語言中調(diào)用PHP/ZE提供的函數(shù)。本文就通過基于Embed SAPI實現(xiàn)一個PHP的opcodes查看器。
首先,下載PHP源碼以供編譯, 我現(xiàn)在使用的是PHP5.3 alpha2
進入源碼目錄:./configure --enable-embed --with-config-file-scan-dir=/etc/php.d --with-mysql --with-config-file-path=/etc/
./make
./make install最后,記得要將生成的libphp5.so復(fù)制到運行時庫的目錄,我直接拷貝到了/lib/, 否則會在運行你自己的embed程序的時候報錯:./embed: error while loading shared libraries: libphp5.so: cannot open shared object file: No such file or directory如果你對PHP的SAPI還不熟悉的話,我建議你看看我的這篇文章:深入理解Zend SAPIs(Zend SAPI Internals)
這個時候,你就可以在你的C代碼中,嵌入PHP腳本解析器了, 我的例子:#include "sapi/embed/php_embed.h"int main(int argc, char * argv[]){ PHP_EMBED_START_BLOCK(argc,argv); char * script = " print 'Hello World!';"; zend_eval_string(script, NULL, "Simple Hello World App" TSRMLS_CC); PHP_EMBED_END_BLOCK(); return 0;}然后就是要指明include path了,一個簡單的MakefileCC = gccCFLAGS = -I/usr/local/include/php/ / -I/usr/local/include/php/main / -I/usr/local/include/php/Zend / -I/usr/local/include/php/TSRM / -Wall -gLDFLAGS = -lstdc++ -L/usr/local/lib -lphp5 $(CC) -o embed embed.cpp $(CFLAGS) $(LDFLAGS)編譯成功以后, 運行,我們可以看到, stdout輸出 Hello World!基于這個,我們就可以很容易的實現(xiàn)一個類似于vld的Opcodes dumper:
首先我們定義opcode的轉(zhuǎn)換函數(shù)(全部的opcodes可以查看Zend/zend_vm_opcodes.h);char *opname(zend_uchar opcode){ switch(opcode) { case ZEND_NOP: return "ZEND_NOP"; break; case ZEND_ADD: return "ZEND_ADD"; break; case ZEND_SUB: return "ZEND_SUB"; break; case ZEND_MUL: return "ZEND_MUL"; break; case ZEND_DIV: return "ZEND_DIV"; break; case ZEND_MOD: return "ZEND_MOD"; break; case ZEND_SL: return "ZEND_SL"; break; case ZEND_SR: return "ZEND_SR"; break; case ZEND_CONCAT: return "ZEND_CONCAT"; break; case ZEND_BW_OR: return "ZEND_BW_OR"; break; case ZEND_BW_AND: return "ZEND_BW_AND"; break; case ZEND_BW_XOR: return "ZEND_BW_XOR"; break; case ZEND_BW_NOT: return "ZEND_BW_NOT"; break; /*...省略 ....*/ default : return "UNKNOW"; break;然后定義zval和znode的輸出函數(shù): char *format_zval(zval *z) html' target='_blank'>static char buffer[BUFFER_LEN]; int len; switch(z- type) { case IS_NULL: return "NULL"; case IS_LONG: case IS_BOOL: snprintf(buffer, BUFFER_LEN, "%d", z- value.lval); return buffer; case IS_DOUBLE: snprintf(buffer, BUFFER_LEN, "%f", z- value.dval); return buffer; case IS_STRING: snprintf(buffer, BUFFER_LEN, "/"%s/"", z- value.str.val); return buffer; case IS_ARRAY: case IS_OBJECT: case IS_RESOURCE: case IS_CONSTANT: case IS_CONSTANT_ARRAY: return ""; default: return "unknown";char * format_znode(znode *n){ static char buffer[BUFFER_LEN]; switch (n- op_type) { case IS_CONST: return format_zval( u.constant); break; case IS_VAR: snprintf(buffer, BUFFER_LEN, "$%d", n- u.var/sizeof(temp_variable)); return buffer; break; case IS_TMP_VAR: snprintf(buffer, BUFFER_LEN, "~%d", n- u.var/sizeof(temp_variable)); return buffer; break; default: return ""; break;}然后定義op_array的輸出函數(shù):void dump_op(zend_op *op, int num){ printf("%5d %5d %30s %040s %040s %040s/n", num, op- lineno, opname(op- opcode), format_znode( op1), format_znode( op2), format_znode( result)) ;void dump_op_array(zend_op_array *op_array){ if(op_array) { int i; printf("%5s %5s %30s %040s %040s %040s/n", "opnum", "line", "opcode", "op1", "op2", "result"); for(i = 0; i op_array- last; i++) { dump_op(&op_array- opcodes[i], i);最后,就是程序的主函數(shù)了:int main(int argc, char **argv){ zend_op_array *op_array; zend_file_handle file_handle; if(argc != 2) { printf("usage: op_dumper script /n"); return 1; PHP_EMBED_START_BLOCK(argc,argv); printf("Script: %s/n", argv[1]); file_handle.filename = argv[1]; file_handle.free_filename = 0; file_handle.type = ZEND_HANDLE_FILENAME; file_handle.opened_path = NULL; op_array = zend_compile_file(&file_handle, ZEND_INCLUDE TSRMLS_CC); if(!op_array) { printf("Error parsing script: %s/n", file_handle.filename); return 1; dump_op_array(op_array); PHP_EMBED_END_BLOCK(); return 0;編譯,運行測試腳本(sample.php):深入理解PHP原理之Opcodes):Script: sample.php
opnum line opcode op1 op2 result
0 2 ZEND_ECHO "laruence"
1 4 ZEND_RETURN 1呵呵,怎么樣,是不是很好玩呢?PHP教程

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 富锦市| 铜山县| 台安县| 滨海县| 周宁县| 敦化市| 永春县| 拜泉县| 革吉县| 游戏| 花莲市| 昌都县| 泾源县| 红安县| 乐陵市| 绥中县| 重庆市| 江阴市| 耒阳市| 沈丘县| 阿合奇县| 锡林郭勒盟| 高雄县| 宝兴县| 皋兰县| 涡阳县| 池州市| 天气| 江门市| 漳浦县| 德令哈市| 长岭县| 高密市| 元谋县| 年辖:市辖区| 盘锦市| 定西市| 寻甸| 麻江县| 建德市| 马边|