c语言编程笔录

您现在的位置是:首页 > 编程 > 编程经验

编程经验

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*)
  • 使用核心函数库或者扩展库函数
  • 扩展的编写者不需要知道结构体的细节
在编写 PHP 扩展时,我们还需要了解其具体的内部机制。PHP 扩展是用 C 语言编写的,因此需要知道可用 C 语言库和头文件,同时还需要了解连接器。 以下是扩展加载和初始化库的代码示例:

扩展库的加载和初始化


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 扩展,还需要掌握更多的知识和技巧。

文章评论