程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> 實現PHP的編譯執行分離(separating compilation and execution)

實現PHP的編譯執行分離(separating compilation and execution)

編輯:PHP綜合

剛剛在PHP群內和大家聊天,應承了大家要寫一個關於如何實現PHP源碼加密的文章,借著這會QA在冒煙的機會,就這個問題,我寫點思路。

我以前的文章介紹過,ZE(Zend engine)執行一個PHP腳本會經歷編譯->執行,只不過它每次執行都會去重新編譯PHP文件。並沒有實現編譯和執行分離。

在ZE的編譯和執行階段,有倆個重要的函數:

ZEND_API zend_op_array *(*zend_compile_file)(zend_file_handle *file_handle, int type TSRMLS_DC);

ZEND_API void (*zend_execute)(zend_op_array *op_array TSRMLS_DC);

zend_compile_file負責將要執行的腳本文件編譯成由ZE的基本指令序列構成的op codes,然後將op codes交由zend_execute執行,從而得到我們腳本的結果。

所以,我們完全可以通過修改默認的zend_complie_file和zend_execute來實現,PHP的執行和編譯分離,進一步,我們還可以再這個基礎上實現,對我們腳本的加密和解密。

我們通過一個PHP擴展模塊來實現這個功能,首先,我們需要在模塊初始化的時候:

PHP_MINIT_FUNCTION(sample)
{
old_compile_file = zend_compile_file; //保存現場
old_execute = zend_execute;
zend_compile_file = my_compile_file; //截獲
zend_execute = my_execute;
return SUCCESS;
}

在我們的my_compile_file中,判斷我們的文件是否是編譯過的文件,假設後綴名是*.ze。

static zend_op_array *my_compile_file(zend_file_handle *file_handle, int type TSRMLS_DC)
{
if(strstr(file_handle->filename, ".ze") != NULL){//是編譯過的文件。
直接返回文件內容.
}
zend_op_array *op_array;
op_array = old_compile_file (file_handle, type TSRMLS_CC); //調用默認的compile,截獲輸出
if(op_array){
保存op_array;
}
return op_array;
}

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved