internals:extensions
Differences
This shows you the differences between two versions of the page.
Both sides previous revisionPrevious revisionNext revision | Previous revisionNext revisionBoth sides next revision | ||
internals:extensions [2013/04/10 10:01] – jpauli | internals:extensions [2013/04/10 13:29] – jpauli | ||
---|---|---|---|
Line 192: | Line 192: | ||
===== Loading the ini parsed extensions ===== | ===== Loading the ini parsed extensions ===== | ||
- | Here comes time where PHP will effectively **load** Zend and PHP extensions, calling some hooks onto them. '' | + | Here comes time where PHP will effectively **load** Zend and PHP extensions, calling some hooks onto them. '' |
First thing to know : **Zend extensions are loaded before PHP extensions** | First thing to know : **Zend extensions are loaded before PHP extensions** | ||
Line 200: | Line 200: | ||
* extension_version_info | * extension_version_info | ||
- | Then API compatibility is checked from extension_version_info against current running PHP. Zend extension' | + | If those symbols are missing, the Zend extension will fail to load |
- | After that, buildid is checked. Buildid is a combinaison of the previously checked API number, debug flag and thread safety flag (ZTS). Other components may be used for buildid check. Zend extension' | + | |
+ | Then API compatibility is checked from '' | ||
+ | After that, buildid is checked. Buildid is a combinaison of the previously checked API number, debug flag and thread safety flag (ZTS). Other components may be used for buildid check. Zend extension' | ||
+ | |||
+ | | ||
+ | |||
+ | After those checks, the Zend extensions get registered. '' | ||
+ | A message is dispatched to all previously registered Zend extension to make them know a new Zend extension is beeing registered. Then, '' | ||
+ | This system has been designed so that Zend extensions may know each other, and eventually fail loading if they guess they are not compatible with each other. | ||
+ | |||
+ | | ||
+ | |||
+ | Finally, the Zend extension is registered, it is then added to an exported global register storing Zend extensions pointers : '' | ||
+ | |||
+ | ==== Loading PHP extensions ==== | ||
+ | After Zend extensions got registered, comes the PHP extensions turn. '' | ||
+ | So, I repeat again : to register a new PHP extension, the engine calls for '' | ||
+ | This does few things : | ||
+ | * Checks for extension dependencies, | ||
+ | * Checks if the extension has already been registered, if it is the case, warns | ||
+ | * Registers the PHP extension functions into the global function table, calling '' | ||
+ | |||
+ | At this stage, the extensions order is not relevant. Extensions are simply registered, nothing more will happen here | ||
+ | |||
+ | PHP extensions registration is quiet the same as Zend extensions registration : dlopen() the shared object, and checks for compatibility. | ||
+ | PHP extensions must export a '' | ||
+ | |||
+ | The '' | ||
+ | <code c> | ||
+ | #define ZEND_GET_MODULE(name) \ | ||
+ | BEGIN_EXTERN_C()\ | ||
+ | ZEND_DLEXPORT zend_module_entry *get_module(void) { return & | ||
+ | END_EXTERN_C() | ||
+ | |||
+ | #ifdef COMPILE_DL_FOO | ||
+ | ZEND_GET_MODULE(foo) | ||
+ | #endif | ||
+ | </ | ||
+ | |||
+ | Then, the two fields '' | ||
+ | |||
+ | After that, the loading mechanism fills in the '' | ||
+ | Now the PHP extension is going to be registered into a shared global variable, called '' | ||
+ | The registration step will perform two checks against the PHP extension beeing registered : | ||
+ | * If the PHP extension is already present in the registry, warning then failure at registration | ||
+ | * PHP extension dependencies **conflicts only** are checked | ||
+ | |||
+ | The system checks for the eventually attached '' | ||
+ | * A PHP extension can tell the system that it is not compatible with another already registered extension, so it will fail loading itself into the engine | ||
+ | * A PHP extension can tell the system that it requires another PHP extension to be loaded before itself | ||
+ | |||
+ | Here, **only conflicts are checked**, and as there is no particular registration order, a PHP extension A could declare beeing in conflict with B, but B could be loaded after A, hence the check wont work and you'll probably get some trouble. | ||
+ | When dealing with conflicts, it is better to sort the extensions in the php.ini file as a FIFO. | ||
+ | **PHP extensions will be registered in the exact same order they' | ||
+ | |||
+ | ==== Activating PHP extensions ==== | ||
+ | After registration, | ||
+ | PHP extensions are activated before Zend extensions | ||
+ | |||
+ | '' | ||
+ | Then comes the " | ||
+ | It checks the extension field '' | ||
+ | Note that conflicts requirements have already been checked against, at extension loading (see last chapter) | ||
+ | After that, the extension globals are registered (call to '' | ||
+ | |||
+ | ==== Activating Zend extensions ==== | ||
+ | Zend extensions are then activated **after** PHP extensions | ||
+ | '' | ||
+ | | ||
+ | '' | ||
+ | Dont be fooled here, it's not the '' | ||
+ | |||
+ | ===== Extensions lifetime ===== | ||
+ | You may know PHP's lifetime. Very basically, '' | ||
+ | We already detailed php_module_startup() previously, to show how both PHP extensions and Zend extensions live into this stage. | ||
+ | |||
+ | ==== Request startup ==== | ||
+ | Zend extensions come first, and their '' | ||
+ | PHP extensions come second, and their '' | ||
+ | |||
+ | ==== Request shutdown ==== | ||
+ | PHP extensions come first, and their '' | ||
+ | Zend extensions come after, and their '' | ||
+ | A third hook is called : '' | ||
+ | |||
+ | ===== Main schema ===== |
internals/extensions.txt · Last modified: 2017/09/22 13:28 by 127.0.0.1