溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

PHP自定義擴展的鉤子功能是什么

發(fā)布時間:2021-12-20 16:04:54 來源:億速云 閱讀:106 作者:iii 欄目:編程語言

本篇內(nèi)容主要講解“PHP自定義擴展的鉤子功能是什么”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“PHP自定義擴展的鉤子功能是什么”吧!

php_module_startup

先看看這個階段做了什么,如果不知道php入口文件在哪,用gdb看看調(diào)用棧,gdb ./php
php_module_startup打斷點,執(zhí)行,在看下調(diào)用棧,

b php_module_startup
(gdb) r test.php
bt
php_module_startup (sf=0x1406460 <cli_sapi_module>, 
    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 <cli_sapi_module>)
    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擴展有關的幾個地方,這里做的初始化工作,像垃圾回收,請求初始化,注冊常量,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里的擴展怎么加載

php_ini_register_extensions();
zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb);

利用這個函數(shù)加載

php_load_extension(char *filename, int type, int start_now)

這里面也執(zhí)行了加載內(nèi)置模塊的功能。

是調(diào)用了module->functions,進行模塊功能函數(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)在看看擴展的幾個鉤子函數(shù)

/* start Zend extensions */
    zend_startup_extensions();

這里的核心就是func(element->data)也就是執(zhí)行擴展

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鉤子可以做很多初始化的功能,怎么注冊一個自定義擴展的功能類,怎么把擴展的變量寫到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);

到此,相信大家對“PHP自定義擴展的鉤子功能是什么”有了更深的了解,不妨來實際操作一番吧!這里是億速云網(wǎng)站,更多相關內(nèi)容可以進入相關頻道進行查詢,關注我們,繼續(xù)學習!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

php
AI