internals:extensions

This is an old revision of the document!


Extensions

This sheet explains how extensions work internally in the engine. We'll see how the get loaded, and what different hooks they provide.

We won't talk about how and why to write an extension.

PHP vs Zend extensions

As you should know, we distinguish between “PHP extensions” and “Zend extensions”. Consider this vocabulary to follow the article, as internally, the sources prefer talking about PHP extensions as “modules” and Zend extensions as “extensions”. We'll keep the more clear “PHP extension” vs “Zend extension” wordings.

Both extension kinds share lots of stuff. The difference between both types is mainly in hooks they register into the Engine.

Here are the PHP extension structures :

typedef struct _zend_module_entry zend_module_entry;
typedef struct _zend_module_dep zend_module_dep;
 
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;
	const char *build_id;
};
 
struct _zend_module_dep {
	const char *name;		/* module name */
	const char *rel;		/* version relationship: NULL (exists), lt|le|eq|ge|gt (to given version) */
	const char *version;	/* version */
	unsigned char type;		/* dependency type */
};

And here are the Zend extension structures :

/* Typedef's for zend_extension function pointers */
typedef int (*startup_func_t)(zend_extension *extension);
typedef void (*shutdown_func_t)(zend_extension *extension);
typedef void (*activate_func_t)(void);
typedef void (*deactivate_func_t)(void);
 
typedef void (*message_handler_func_t)(int message, void *arg);
 
typedef void (*op_array_handler_func_t)(zend_op_array *op_array);
 
typedef void (*statement_handler_func_t)(zend_op_array *op_array);
typedef void (*fcall_begin_handler_func_t)(zend_op_array *op_array);
typedef void (*fcall_end_handler_func_t)(zend_op_array *op_array);
 
typedef void (*op_array_ctor_func_t)(zend_op_array *op_array);
typedef void (*op_array_dtor_func_t)(zend_op_array *op_array);
 
typedef struct _zend_extension {
	char *name;
	char *version;
	char *author;
	char *URL;
	char *copyright;
 
	startup_func_t startup;
	shutdown_func_t shutdown;
	activate_func_t activate;
	deactivate_func_t deactivate;
 
	message_handler_func_t message_handler;
 
	op_array_handler_func_t op_array_handler;
 
	statement_handler_func_t statement_handler;
	fcall_begin_handler_func_t fcall_begin_handler;
	fcall_end_handler_func_t fcall_end_handler;
 
	op_array_ctor_func_t op_array_ctor;
	op_array_dtor_func_t op_array_dtor;
 
	int (*api_no_check)(int api_no);
	int (*build_id_check)(const char* build_id);
	void *reserved3;
	void *reserved4;
	void *reserved5;
	void *reserved6;
	void *reserved7;
	void *reserved8;
 
	DL_HANDLE handle;
	int resource_number;
} zend_extension;
 
typedef struct _zend_extension_version_info {
	int zend_extension_api_no;
	char *build_id;
} zend_extension_version_info;

Statically compiled extensions

All extensions may be built statically or dynamically. When built statically, the extension is loaded earlier than when its built dynamically and loaded throught php.ini. So, the first thing to remember is that an extension may behave differently if it is loaded statically against dynamically, at least if the maintainer has not taken care of such a behavior.

internals/extensions.1365524593.txt.gz · Last modified: 2017/09/22 13:28 (external edit)