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. |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||