PHP开发解读 PHP 扩展开发的内部原理
曹敏侑 2023-07-10编程经验
第一段:扩展是PHP能力的一个重要组成部分,它提供了扩展PHP的能力。我们通过开发扩展来提高PHP的运行效率和扩展其支持的特定功能。PHP扩展本质上是一个具有共享库格式的二进制文件,可以直接加载到
第一段:
扩展是 PHP 能力的一个重要组成部分,它提供了扩展 PHP 的能力。我们通过开发扩展来提高 PHP 的运行效率和扩展其支持的特定功能。 PHP 扩展本质上是一个具有共享库格式的二进制文件,可以直接加载到 PHP 运行时环境中。本段将解释 PHP 扩展开发的内部原理。
一般情况下,PHP 提供了自己的 C 库,接受来自其它模块的调用。开发人员可以通过这个 C 库来实现 PHP 扩展并将其加载到 PHP 运行时环境中。
我们可以通过以下代码结构创建和初始化一个简单的 PHP 扩展:
初始化 PHP 扩展
#define PHP_MYEXTENSION_VERSION "1.0"
#define PHP_MYEXTENSION_EXTNAME "myextension"
PHP_MINIT_FUNCTION(myextension) {
return SUCCESS;
}
PHP_MSHUTDOWN_FUNCTION(myextension) {
return SUCCESS;
}
PHP_RINIT_FUNCTION(myextension) {
return SUCCESS;
}
PHP_RSHUTDOWN_FUNCTION(myextension) {
return SUCCESS;
}
PHP_MINFO_FUNCTION(myextension){
php_info_print_table_start();
php_info_print_table_header(2, "myextension support", "enabled");
php_info_print_table_end();
}
zend_module_entry myextension_module_entry = {
STANDARD_MODULE_HEADER,
PHP_MYEXTENSION_EXTNAME,
NULL,
PHP_MINIT(myextension),
PHP_MSHUTDOWN(myextension),
PHP_RINIT(myextension),
PHP_RSHUTDOWN(myextension),
PHP_MINFO(myextension),
PHP_MYEXTENSION_VERSION,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_MYEXTENSION
ZEND_GET_MODULE(myextension)
#endif
此代码中,我们首先定义了 PHP 扩展的名称和版本号。然后,我们定义了扩展中的基本函数 myextension_module_entry。这个函数包括了扩展的启动、卸载、请求初始化和请求卸载函数以及其他一些初始化函数。最后,我们使用宏 COMPILE_DL_MYEXTENSION 定义动态链接库,以便 PHP 在编译时将其打包为动态链接库。
第二段:
在我们开发 PHP 扩展时,需要了解 Zend 引擎的内部机制和数据结构。 Zend 引擎是 PHP 的核心,负责将 PHP 代码编译和解释执行。以下代码是 Zend 引擎中的一些基本数据结构:
Zend 数据结构
typedef struct _zend_string zend_string;
typedef struct _zend_execute_data zend_execute_data;
typedef struct _zend_op zend_op;
typedef struct _zval_struct zval;
typedef struct _zend_class_entry zend_class_entry;
这些结构体是在 Zend 引擎中广泛使用的,因此开发 PHP 扩展时应熟悉这些结构体的用法。
除了熟悉 Zend 数据结构外,我们还需要掌握扩展的导出接口。以下是一些常用的扩展导出接口:
扩展导出接口
ZEND_FUNCTION(myfunction);
PHP_FUNCTION(myfunction);
PHP_MINIT_FUNCTION(myextension);
PHP_MSHUTDOWN_FUNCTION(myextension);
PHP_RINIT_FUNCTION(myextension);
PHP_RSHUTDOWN_FUNCTION(myextension);
PHP_MINFO_FUNCTION(myextension);
Zend_FUNCTION 返回 void,PHP_FUNCTION 返回 zval*。
第三段:
扩展的工作原理实际上就是提供了一个可单独加载的库,它不依赖于 PHP,同时也可以使用 PHP 的初始化和配置文件。此外,PHP 扩展有以下特点:
- 运行时内存分配和释放
- 不需要使用 zval 类型参数(指针类型为 zval*)
- 使用核心函数库或者扩展库函数
- 扩展的编写者不需要知道结构体的细节
扩展库的加载和初始化
zend_module_entry myextension_module_entry = {
STANDARD_MODULE_HEADER,
PHP_MYEXTENSION_EXTNAME,
NULL, /* functions */
PHP_MINIT(myextension),
PHP_MSHUTDOWN(myextension),
NULL, /* RINIT */
NULL, /* RSHUTDOWN */
PHP_MINFO(myextension),
PHP_MYEXTENSION_VERSION,
STANDARD_MODULE_PROPERTIES
};
#ifdef COMPILE_DL_MYEXTENSION
ZEND_GET_MODULE(myextension)
#endif
ZEND_DECLARE_MODULE_GLOBALS(myextension)
static void myextension_init_globals(zend_myextension_globals *myextension_globals)
{
myextension_globals->myvalue = 0;
}
PHP_MINIT_FUNCTION(myextension)
{
ZEND_INIT_MODULE_GLOBALS(myextension, myextension_init_globals, NULL);
return SUCCESS;
}
此代码中,我们定义了扩展模块,并定义了模块中的函数。然后我们定义了 Zend 数据结构,并初始化 Zend 模块,并在模块导出期间初始化模块的全局变量。
第四段:
在 C 语言中,我们使用指针来访问内存,但在 PHP 扩展中,我们可以使用 zval* 类型和 HashTable* 类型来访问 Zend 引擎中的内存。以下是一些常用的函数:
常用函数
Z_TYPE_PP(zval_pp);
Z_ARRVAL_PP(zval_pp);
Z_STRVAL_PP(zval_pp);
zend_hash_next_index_insert(hash, (void **)&data, sizeof(char *));
zend_hash_apply_with_argument(&function_table, (apply_func_arg_t)my_function, (void *)&argument TSRMLS_CC);
这些函数可以帮助我们访问内存,插入和查询哈希表以及执行扩展中的函数。
总结:
本文介绍了 PHP 扩展开发的基本原理、内部工作机制以及常见函数的使用。我们了解了扩展中的基本结构和函数、Zend 引擎中的数据结构以及扩展的导出接口。当然,要开发真正的 PHP 扩展,还需要掌握更多的知识和技巧。
很赞哦! ()