|
The zend_module structureThe main source file of a PHP extension contains several new constructs for a C programmer. The most important of these, the one touched first when starting a new extension, is the zend_module structure. This structure contains a wealth of information that tells the Zend Engine about the extension's dependencies, version, callbacks, and other critical data. The structure has mutated considerably over time; this section will focus on the structure as it has appeared since PHP 5.2, and will identify the very few parts which have changed in PHP 5.3. The zend_module declaration from counter.c looks like this before any code has been written. The example file was generated by ext_skel --extname=counter, with some obsolete constructs removed: Пример #1 zend_module declaration in the counter extension /* {{{ counter_module_entry */ zend_module_entry counter_module_entry = { STANDARD_MODULE_HEADER, "counter", counter_functions, PHP_MINIT(counter), PHP_MSHUTDOWN(counter), PHP_RINIT(counter), /* Replace with NULL if there's nothing to do at request start */ PHP_RSHUTDOWN(counter), /* Replace with NULL if there's nothing to do at request end */ PHP_MINFO(counter), "0.1", /* Replace with version number for your extension */ STANDARD_MODULE_PROPERTIES }; /* }}} */ This may look a bit daunting at first glance, but most of it is very simple to understand. Here's the declaration of zend_module from zend_modules.h in PHP 5.3: Пример #2 zend_module definition in PHP 5.3 struct _zend_module_entry { unsigned short size; unsigned int zend_api; unsigned char zend_debug; unsigned char zts; const struct _zend_ini_entry *ini_entry; const struct _zend_module_dep *deps; const char *name; const struct _zend_function_entry *functions; int (*module_startup_func)(INIT_FUNC_ARGS); int (*module_shutdown_func)(SHUTDOWN_FUNC_ARGS); int (*request_startup_func)(INIT_FUNC_ARGS); int (*request_shutdown_func)(SHUTDOWN_FUNC_ARGS); void (*info_func)(ZEND_MODULE_INFO_FUNC_ARGS); const char *version; size_t globals_size; #ifdef ZTS ts_rsrc_id* globals_id_ptr; #else void* globals_ptr; #endif void (*globals_ctor)(void *global TSRMLS_DC); void (*globals_dtor)(void *global TSRMLS_DC); int (*post_deactivate_func)(void); int module_started; unsigned char type; void *handle; int module_number; }; Many of these fields will never be touched by an extension writer. There are a number of standard macros that set them to their proper values automatically. The macro STANDARD_MODULE_HEADER fills in everything up to the deps field. Alternatively, the STANDARD_MODULE_HEADER_EX will leave the deps field empty for the developer's use. The developer is always responsible for everything from name to version. After that, the STANDARD_MODULE_PROPERTIES macro will fill in the rest of the structure, or the STANDARD_MODULE_PROPERTIES_EX macro can be used to leave the extension globals and post-deactivation function fields unfilled. Most modern extensions will make use of module globals.
Filling in the structure in a practical situationWith all these fields to play with, it can be confusing to know which to use for what purpose. Here is the zend_module definition from the "counter" example extension after updating it to its final form. Пример #3 Counter extension module definition /* {{{ counter_module_entry */ zend_module_entry counter_module_entry = { STANDARD_MODULE_HEADER, "counter", counter_functions, PHP_MINIT(counter), PHP_MSHUTDOWN(counter), PHP_RINIT(counter), PHP_RSHUTDOWN(counter), PHP_MINFO(counter), NO_VERSION_YET, PHP_MODULE_GLOBALS(counter), PHP_GINIT(counter), PHP_GSHUTDOWN(counter), NULL, STANDARD_MODULE_PROPERTIES_EX }; /* }}} */
What's changed between 5.2 and 5.3?Nothing. The only differences in the zend_module structure between PHP 5.2 and PHP 5.3 are a few const keywords. |
|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||