[Switch] PHP execution process, PHP Extension loading process, and php loading. [Switch] PHP execution process, PHP Extension loading process, php loading original: www. imsiren. comarchives535 to develop PHP extensions later .. you must understand the PHP execution sequence .. this article [go to] PHP execution process, PHP Extension loading process, php loading
Original article: http://www.imsiren.com/archives/535
To develop PHP extensions in the future, you must understand the PHP execution sequence. This article paves the way for C to develop PHP extensions.
The web environment is apache.
When compiling PHP, in order to make Apache support PHP, we will generate a mod_php5.so module. apache loads this module ..
When the url accesses the. php file, it will be transferred to the mod_php5.so module for processing. What is this? it is what we often call SAPI.
The English name is Server login action API.
SAPI is a general term under which ISAPI, cli sapi, CGI, and so on.
With it, you can easily interact with other things, such as APACHE, IIS, CGI, etc.
Now, let's go back to the topic.
After apache is started, it will register the hook handler of the mod_pho5.so module. apache is not the main character today, so I will not elaborate on it.
When APACHE detects that the Accessed url is a PHP file, the control will be handed over to sapi.
For example:
After entering sapi, the php_init_handler function of the sapi/apache/mod_php5.c file is executed first.
| 1234567891011121314151617181920 |
static void php_init_handler(server_rec *s, pool *p){ register_cleanup(p, NULL, (void (*)(void *))apache_php_module_shutdown_wrapper, (void (*)(void *))php_module_shutdown_for_exec); if (!apache_php_initialized) { apache_php_initialized = 1;#ifdef ZTS tsrm_startup(1, 1, 0, NULL);#endif sapi_startup(&apache_sapi_module); php_apache_startup(&apache_sapi_module); }#if MODULE_MAGIC_NUMBER >= 19980527 { TSRMLS_FETCH(); if (PG(expose_php)) { ap_add_version_component("PHP/" PHP_VERSION); } }#endif} |
This function mainly calls two functions
Sapi_startup (& apache_sapi_module );
Php_apache_startup (& apache_sapi_module );
| 123456789101112131415 |
SAPI_API void sapi_startup(sapi_module_struct *sf){ sf->ini_entries = NULL; sapi_module = *sf; ................. sapi_globals_ctor(&sapi_globals);................ virtual_cwd_startup(); /* Could use shutdown to free the main cwd but it would just slow it down for CGI */ .................. reentrancy_startup();} |
Sapi_startup creates a sapi_globals_struct struct.
Sapi_globals_struct stores the basic information of apache requests, such as server information, header, and encoding.
| 123456 |
static void sapi_globals_ctor(sapi_globals_struct *sapi_globals TSRMLS_DC){ memset(sapi_globals, 0, sizeof(*sapi_globals)); zend_hash_init_ex(&sapi_globals->known_post_content_types, 5, NULL, NULL, 1, 0); php_setup_sapi_content_types(TSRMLS_C);} |
Known_post_content_types is a HashTable that initializes its size to 5. literally, I guess it stores the content type passed by the client.
The php_setup_sapi_content_types function adds sapi_post_entry to sapi_globals.
After sapi_startup is executed, execute php_apache_startup.
| 12345678 |
static int php_apache_startup(sapi_module_struct *sapi_module){ if (php_module_startup(sapi_module, &apache_module_entry, 1) == FAILURE) { return FAILURE; } else { return SUCCESS; }} |
There are too many php_module_startup contents.
1. initialize the zend_utility_functions structure. this structure is used to set zend function pointers, such as error handling functions, output functions, and stream operation functions.
2. set environment variables.
3. load the php. ini configuration.
4. load php built-in extensions.
5. write logs.
6. Register the internal function set of php.
7. call php_ini_register_extensions to load all external extensions.
8. enable all extensions
9. some cleanup operations.
Let's focus on 3, 4, 7, and 8.
Load php. ini configuration
If (php_init_config (TSRMLS_C) = FAILURE ){
Return FAILURE;
}
The php_init_config function checks all php. ini configurations, finds all loaded modules, and adds them to the php_extension_lists structure.
Loading php built-in extensions
Call zend_register_standard_ini_entries to load all built-in php extensions, such as array and mysql.
Call php_ini_register_extensions to load all external extensions.
Main/php_ini.c
| 12345678 |
void php_ini_register_extensions(TSRMLS_D){ zend_llist_apply(&extension_lists.engine, php_load_zend_extension_cb TSRMLS_CC); zend_llist_apply(&extension_lists.functions, php_load_php_extension_cb TSRMLS_CC); zend_llist_destroy(&extension_lists.engine); zend_llist_destroy(&extension_lists.functions);} |
The zend_llist_apply function traverses extension_lists and the php_load_php_extension_cb function will be dropped during execution.
Php_load_php_extension_cb
| 1234 |
static void php_load_zend_extension_cb(void *arg TSRMLS_DC){ zend_load_extension(*((char **) arg));} |
Call ext/standard/dl. c zend_load_extension to load the extension,
This function is skipped ..
The last call of this function
If (module_entry = zend_register_module_ex (module_entry TSRMLS_CC) = NULL ){
DL_UNLOAD (handle );
Return FAILURE;
}
Put the extended information in the module_registry Hash table.
Zend/zend_API.c
| 12345 |
if (zend_hash_add(&module_registry, lcname, name_len+1, (void *)module, sizeof(zend_module_entry), (void**)&module_ptr)==FAILURE) { zend_error(E_CORE_WARNING, "Module '%s' already loaded", module->name); efree(lcname); return NULL;} |
Last
Zend_startup_modules (TSRMLS_C); // sorts the modules and checks whether the modules are registered in the module_registry HASH table.
Zend_startup_extensions (); // execute extension-> startup (extension); start extension...
Original article: http://www.imsiren.com/archives/535 in order to develop PHP extension in the future... we must understand the PHP execution order... this article...