Home > Backend Development > PHP Problem > How to customize PHP extension (2) hook function

How to customize PHP extension (2) hook function

藏色散人
Release: 2023-03-14 14:32:01
forward
2087 people have browsed it

Following previous article let’s talk about the php life cycle and see which hooks are extended to do what, php There are about 5 stages in the life cycle, module initialization stagephp_module_startup, request initialization stagephp_request_startup, script execution stagephp_execute_script, request shutdown stagephp_request_shutdown ,Module shutdown phasephp_module_shutdown, introduced below in cli mode.

php_module_startup

First take a look at what is done at this stage. If you don’t know where the php entry file is, use gdb to look at the call stack, gdb ./ php

At the php_module_startup break point, execute, look at the call stack,

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
Copy after login

You can clearly see the execution process in the call stack, now go to/ main/main.c file to see what has been done. You can also use gdb to see it step by step. Here are a few places related to PHP extensions. The initialization work done here, such as garbage collection, request initialization, and registered constants. php.ini configuration file loading, etc.

Let’s first look at how to load the module

/* startup extensions statically compiled in */
    if (php_register_internal_extensions_func() == FAILURE) {
        php_printf("Unable to start builtin modules\n");
        return FAILURE;
    }
Copy after login

Here is to load the built-in module of php. Only the core functions are posted here. Check the dependencies first

/* 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;
        }
    }
Copy after login
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;
    }
Copy after login

This is the principle of loading built-in modules. Now let’s see how to load the extension in ini

php_ini_register_extensions();
Copy after login
zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb);
Copy after login

Use this function to load

php_load_extension(char *filename, int type, int start_now)
Copy after login

This also performs the function of loading built-in modules.

is calling module->functions to register the module function function. Now we know why the function function should be written in helloworld_functions here

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
};
Copy after login

Now look at several hook functions of the extension

/* start Zend extensions */
    zend_startup_extensions();
Copy after login

The core here isfunc(element->data)That is, executing the extension

PHP_MINIT Function

element=l->head;
    while (element) {
        next = element->next;
        if (func(element->data)) {
            DEL_LLIST_ELEMENT(element, l);
        }
        element = next;
    }
Copy after login

Now we know thatPHP_MINITThe hook can do many initialization functions. How to register a custom extended function class and how to write the extended variables into php.ini , how to rewrite php built-in functions,

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);
Copy after login

Here is to rewrite the var_dump function, register a person class, introduce it here first, Next article will introduce how to pass php code through lexical analysis Syntax analysis generates AST, and then compiles opcode instructions for call by zend virtual machine.

Recommended learning: "PHP Video Tutorial"

The above is the detailed content of How to customize PHP extension (2) hook function. For more information, please follow other related articles on the PHP Chinese website!

Related labels:
source:segmentfault.com
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template