-Opcache將操作數(shù)組存儲在共享內(nèi)存中以獲得更好的性能,因此,每當(dāng)腳本被編譯時,其最終的操作數(shù)組都會從緩存中得到服務(wù),而不是重新編譯。您可以在ext / opcache / ZendAccelerator.c中找到此實(shí)現(xiàn)。
-名為compile_file的默認(rèn)實(shí)現(xiàn)是Zend / zend_language_scanner.l中掃描程序代碼的一部分。
實(shí)施此掛鉤的用例是Opcode Accelerating,PHP代碼加密/解密,調(diào)試或概要分析。
您可以隨時在執(zhí)行PHP進(jìn)程時替換該掛鉤,并且替換后編譯的所有PHP腳本都將由該掛鉤的實(shí)現(xiàn)處理。
始終調(diào)用原始函數(shù)指針非常重要,否則PHP將無法再編譯腳本,并且Opcache將不再起作用。
此處的擴(kuò)展覆蓋順序也很重要,因?yàn)槟枰朗且贠pcache之前還是之后注冊鉤子,因?yàn)镺pcache如果在其共享內(nèi)存緩存中找到操作碼數(shù)組條目,則不會調(diào)用原始函數(shù)指針。 Opcache將其鉤子注冊為啟動后鉤子,該鉤子在擴(kuò)展的minit階段之后運(yùn)行,因此默認(rèn)情況下,緩存腳本時將不再調(diào)用該鉤子。
調(diào)用錯誤處理程序時的通知
與PHP用戶區(qū)set_error_handler()函數(shù)類似,擴(kuò)展可以通過實(shí)現(xiàn)zend_error_cb鉤子將自身注冊為錯誤處理程序:
ZEND_API void(* zend_error_cb)(int類型,const char * error_filename,const uint32_t error_lineno,const char * format,va_list args);
type變量對應(yīng)于E _ *錯誤常量,該常量在PHP用戶區(qū)中也可用。
PHP核心和用戶態(tài)錯誤處理程序之間的關(guān)系很復(fù)雜:
1.如果未注冊任何用戶級錯誤處理程序,則始終調(diào)用zend_error_cb。
2.如果注冊了userland錯誤處理程序,則對于E_ERROR,E_PARSE,E_CORE_ERROR,E_CORE_WARNING,E_COMPILE_ERROR的所有錯誤和E_COMPILE_WARNING始終調(diào)用zend_error_cb掛鉤。
3.對于所有其他錯誤,僅在用戶態(tài)處理程序失敗或返回false時調(diào)用zend_error_cb。
另外,由于Xdebug自身復(fù)雜的實(shí)現(xiàn),它以不調(diào)用以前注冊的內(nèi)部處理程序的方式覆蓋錯誤處理程序。
因此,覆蓋此掛鉤不是很可靠。
再次覆蓋應(yīng)該以尊重原始處理程序的方式進(jìn)行,除非您想完全替換它:
void(* original_zend_error_cb)(int類型,const char * error_filename,const uint error_lineno,const char * format,va_list args);void my_error_cb(int類型,const char * error_filename,const uint error_lineno,const char * format,va_list args){
//我的特殊錯誤處理
original_zend_error_cb(type,error_filename,error_lineno,format,args);}PHP_MINIT_FUNCTION(my_extension){
original_zend_error_cb = zend_error_cb;
zend_error_cb = my_error_cb;
return SUCCESS;}PHP_MSHUTDOWN(my_extension){
zend_error_cb = original_zend_error_cb;}
該掛鉤主要用于為異常跟蹤或應(yīng)用程序性能管理軟件實(shí)施集中式異常跟蹤。
引發(fā)異常時的通知
每當(dāng)PHP Core或Userland代碼引發(fā)異常時,都會調(diào)用zend_throw_exception_hook并將異常作為參數(shù)。
這個鉤子的簽名非常簡單:
void my_throw_exception_hook(zval * exception){
if(original_zend_throw_exception_hook!= NULL){
original_zend_throw_exception_hook(exception);
}}
該掛鉤沒有默認(rèn)實(shí)現(xiàn),如果未被擴(kuò)展覆蓋,則指向NULL。
static void(* original_zend_throw_exception_hook)(zval * ex);void my_throw_exception_hook(zval * exception);PHP_MINIT_FUNCTION(my_extension){
original_zend_throw_exception_hook = zend_throw_exception_hook;
zend_throw_exception_hook = my_throw_exception_hook;
return SUCCESS;}
如果實(shí)現(xiàn)此掛鉤,請注意無論是否捕獲到異常,都會調(diào)用此掛鉤。將異常臨時存儲在此處,然后將其與錯誤處理程序掛鉤的實(shí)現(xiàn)結(jié)合起來以檢查異常是否未被捕獲并導(dǎo)致腳本停止,仍然有用。
實(shí)現(xiàn)此掛鉤的用例包括調(diào)試,日志記錄和異常跟蹤。
掛接到eval()
PHPeval不是內(nèi)部函數(shù),而是一種特殊的語言構(gòu)造。因此,您無法通過zend_execute_internal或通過覆蓋其函數(shù)指針來連接它。
掛鉤到eval的用例并不多,您可以將其用于概要分析或出于安全目的。如果更改其行為,請注意可能需要評估其他擴(kuò)展名。一個示例是Xdebug,它使用它執(zhí)行斷點(diǎn)條件。
extern ZEND_API zend_op_array *(* zend_compile_string)(zval * source_string,char * filename);
掛入垃圾收集器
當(dāng)可收集對象的數(shù)量達(dá)到一定閾值時,引擎本身會調(diào)用gc_collect_cycles()或隱式地觸發(fā)PHP垃圾收集器。
為了使您了解垃圾收集器的工作方式或分析其性能,可以覆蓋執(zhí)行垃圾收集操作的函數(shù)指針掛鉤。從理論上講,您可以在此處實(shí)現(xiàn)自己的垃圾收集算法,但是如果有必要對引擎進(jìn)行其他更改,則這可能實(shí)際上并不可行。
int(* original_gc_collect_cycles)(無效);int my_gc_collect_cycles(無效){
original_gc_collect_cycles();}PHP_MINIT_FUNCTION(my_extension){
original_gc_collect_cycles = gc_collect_cycles;
gc_collect_cycles = my_gc_collect_cycles;
return SUCCESS;}
覆蓋中斷處理程序
當(dāng)執(zhí)行器全局EG(vm_interrupt)設(shè)置為1時,將調(diào)用一次中斷處理程序。在執(zhí)行用戶域代碼期間,將在常規(guī)檢查點(diǎn)對它進(jìn)行檢查。引擎使用此掛鉤通過信號處理程序?qū)崿F(xiàn)PHP執(zhí)行超時,該信號處理程序在達(dá)到超時持續(xù)時間后將中斷設(shè)置為1。
當(dāng)更安全地清理或?qū)崿F(xiàn)自己的超時處理時,這有助于將信號處理推遲到運(yùn)行時執(zhí)行的后期。通過設(shè)置此掛鉤,您不會意外禁用PHP的超時檢查,因?yàn)樗哂凶远x處理的優(yōu)先級,該優(yōu)先級高于對zend_interrupt_function的任何覆蓋。
ZEND_API void(* original_interrupt_function)(zend_execute_data * execute_data);void my_interrupt_function(zend_execute_data * execute_data){
if(original_interrupt_function!= NULL){
original_interrupt_function(execute_data);
}}PHP_MINIT_FUNCTION(my_extension){
original_interrupt_function = zend_interrupt_function;
zend_interrupt_function = my_interrupt_function;
return SUCCESS;}
##替換操作碼處理程序
TODO
更多關(guān)于云服務(wù)器,域名注冊,虛擬主機(jī)的問題,請?jiān)L問西部數(shù)碼官網(wǎng):m.ps-sw.cn