新聞中心
接著上篇來講php生命周期,看看擴(kuò)展哪些鉤子做哪些事,php生命周期大概5個(gè)階段,模塊初始化階段php_module_startup,請求初始化階段php_request_startup,腳本執(zhí)行階段php_execute_script,請求關(guān)閉階段php_request_shutdown,模塊關(guān)閉階段php_module_shutdown,下面以cli模式介紹。

站在用戶的角度思考問題,與客戶深入溝通,找到鄲城網(wǎng)站設(shè)計(jì)與鄲城網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗(yàn),讓設(shè)計(jì)與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個(gè)性化、用戶體驗(yàn)好的作品,建站類型包括:網(wǎng)站建設(shè)、成都網(wǎng)站設(shè)計(jì)、企業(yè)官網(wǎng)、英文網(wǎng)站、手機(jī)端網(wǎng)站、網(wǎng)站推廣、域名注冊、網(wǎng)頁空間、企業(yè)郵箱。業(yè)務(wù)覆蓋鄲城地區(qū)。
php_module_startup
先看看這個(gè)階段做了什么,如果不知道php入口文件在哪,用gdb看看調(diào)用棧,gdb ./php
在php_module_startup打斷點(diǎn),執(zhí)行,在看下調(diào)用棧,
b php_module_startup (gdb) r test.php bt php_module_startup (sf=0x1406460, additional_modules=0x0, num_additional_modules=0) at /www/test/php/php-7.4.3/main/main.c:2098 #1 0x00000000008bae7c in php_cli_startup ( sapi_module=0x1406460 ) at /www/test/php/php-7.4.3/sapi/cli/php_cli.c:407 #2 0x00000000008bcc80 in main (argc=2, argv=0x1425af0) at /www/test/php/php-7.4.3/sapi/cli/php_cli.c:1323
在調(diào)用棧可以清楚看到執(zhí)行流程,現(xiàn)在到/main/main.c文件看看做了哪些事情,也可以用gdb一步一步的看,這里就講與php擴(kuò)展有關(guān)的幾個(gè)地方,這里做的初始化工作,像垃圾回收,請求初始化,注冊常量,php.ini配置文件加載等,
先來看看怎么加載模塊的
/* startup extensions statically compiled in */
if (php_register_internal_extensions_func() == FAILURE) {
php_printf("Unable to start builtin modules\n");
return FAILURE;
}
這里是加載php內(nèi)置的模塊,這里只貼出核心功能,先檢查依賴
/* Check module dependencies */
if (module->deps) {
const zend_module_dep *dep = module->deps;
while (dep->name) {
if (dep->type == MODULE_DEP_CONFLICTS) {
name_len = strlen(dep->name);
lcname = zend_string_alloc(name_len, 0);
zend_str_tolower_copy(ZSTR_VAL(lcname), dep->name, name_len);
if (zend_hash_exists(&module_registry, lcname) || zend_get_extension(dep->name)) {
zend_string_efree(lcname);
/* TODO: Check version relationship */
zend_error(E_CORE_WARNING, "Cannot load module '%s' because conflicting module '%s' is already loaded", module->name, dep->name);
return NULL;
}
zend_string_efree(lcname);
}
++dep;
}
}
if (module->functions && zend_register_functions(NULL, module->functions, NULL, module->type)==FAILURE) {
zend_hash_del(&module_registry, lcname);
zend_string_release(lcname);
EG(current_module) = NULL;
zend_error(E_CORE_WARNING,"%s: Unable to register functions, unable to load", module->name);
return NULL;
}
這是內(nèi)置模塊加載原理,現(xiàn)在看看ini里的擴(kuò)展怎么加載
php_ini_register_extensions();
zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb);
利用這個(gè)函數(shù)加載
php_load_extension(char *filename, int type, int start_now)
這里面也執(zhí)行了加載內(nèi)置模塊的功能。
是調(diào)用了module->functions,進(jìn)行模塊功能函數(shù)注冊,現(xiàn)在知道了為什么功能函數(shù)要寫在helloworld_functions這里吧
zend_module_entry helloworld_module_entry = {
STANDARD_MODULE_HEADER,
"helloworld", /* Extension name */
helloworld_functions, /* zend_function_entry */
PHP_MINIT(helloworld), /* PHP_MINIT - Module initialization */
NULL, /* PHP_MSHUTDOWN - Module shutdown */
PHP_RINIT(helloworld), /* PHP_RINIT - Request initialization */
NULL, /* PHP_RSHUTDOWN - Request shutdown */
PHP_MINFO(helloworld), /* PHP_MINFO - Module info */
PHP_HELLOWORLD_VERSION, /* Version */
PHP_MODULE_GLOBALS(pib),
NULL,
NULL,
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
現(xiàn)在看看擴(kuò)展的幾個(gè)鉤子函數(shù)
/* start Zend extensions */
zend_startup_extensions();
這里的核心就是func(element->data)也就是執(zhí)行擴(kuò)展
PHP_MINIT函數(shù)
element=l->head;
while (element) {
next = element->next;
if (func(element->data)) {
DEL_LLIST_ELEMENT(element, l);
}
element = next;
}
現(xiàn)在就知道PHP_MINIT鉤子可以做很多初始化的功能,怎么注冊一個(gè)自定義擴(kuò)展的功能類,怎么把擴(kuò)展的變量寫到php.ini里面,怎么重寫php內(nèi)置函數(shù),
original = zend_hash_str_find_ptr(CG(function_table), "var_dump", sizeof("var_dump")-1);
if (original != NULL) {
original->internal_function.handler = my_overwrite_var_dump;
}
zend_class_entry person;
INIT_CLASS_ENTRY(person,CLASS_NAME,person_functions);
zend_register_internal_class_ex(&person,NULL);
這里就是重寫var_dump函數(shù),注冊了一個(gè)person類,先介紹到這里,下篇就介紹怎么把php代碼通過詞法分析語法分析生成AST,然后編譯opcode指令,供zend虛擬機(jī)調(diào)用。
當(dāng)前文章:PHP如何自定義擴(kuò)展(二)之鉤子功能
本文地址:http://www.dlmjj.cn/article/ccisdcg.html


咨詢
建站咨詢
