如何下载PHP源代码并开发PHP扩展:PHP-7.0.2源码解析与Zend、ext目录详解
下载PHP源代码

要开发PHP扩展,您需要先下载PHP源代码。一方面,我们的扩展一般使用PHP本身定义的函数和宏。另一方面,我们可以使用官方工具来减少工作量。
我下载的是PHP-7.0.2,地址是:。
解压源代码存档,tar xzf php-7.0.2.tar.gz。我们现在只需要关注 Zend 和 ext 目录。
Zend目录包含PHP的Zend Engine源代码。这里我们需要简单看一下一些函数和宏的定义。
ext 目录包含 PHP 本机扩展和我们在开发自己的扩展时可以使用的工具。我们在Linux下使用ext_skel,在Windows下使用ext_skel_win32.php。
使用 ext_skel 工具
我们可以在ext目录下看到所有的PHP原生扩展,包括我们熟悉的curl、json、mbstring、simplexml、sockets等扩展。还有很多扩展没有使用过,甚至没有听说过。这些先不用管,我们先打开我们最熟悉的卷曲来看看。其中有config.m4配置文件、php_curl.h、curl_file.c等源码,以及一些中间文件,最后还有一个tests目录,里面包含curl扩展单元。测试。只需关注config.m4、php_curl.h 和curl_file.c。在最简单的情况下,这三个文件都是扩展的组件。
打开它看看。不算太复杂,但是自己写一个类似的还是很头疼。这时候就需要用到我前面提到的ext_skel工具了。这个工具也在ext目录下。我们执行./ext_skel --help,可以看到几个参数。我们使用的唯一一个是--extname=module。这里填写你开发的扩展名称。如果你想详细了解各个参数的作用,可以阅读这里:
./ext_skel --extname=hello
ext目录下多了一个hello目录。我们后续的工作都会在这个目录下。该工具自动为我们生成了一些文件。
config.m4 配置文件
要开发 PHP 扩展,必须在编写 C 代码之前进行配置。当我们打开它时,我们可以看到详细的注释说明。 dnl 是注释语法。
如果您的扩展使用外部依赖项,请配置 --with-hello 选项。否则,配置 --enable-hello 选项并删除以下三行中的 dnl 注释。
PHP_ARG_ENABLE(hello, whether to enable hello support,
Make sure that the comment is aligned:
[ --enable-hello Enable hello support])
PHP_ARG_WITH 和 PHP_ARG_ENABLE 这两个宏用于配置配置选项。一种配置需要外部依赖项,另一种配置不需要外部依赖项。
稍后执行configure --help 即可看到配置的内容。
php_hello.h 头文件
一个类似C语音的头文件,包括一些自定义的结构体和函数声明,本demo中暂时不需要改动。
hello.c 代码文件
真正的逻辑代码就在这个文件中,后面会详细介绍。
写代码
好的,此时我们终于要开始编写代码并打开 hello.c 文件了。
整个扩展的入口是zend_module_entry结构体。具体定义可以参见Zend目录下的zend_modules.h文件。总共有十几个属性。赶紧跳过,我们暂时只需要“hello world”。
zend_module_entry hello_module_entry = {
STANDARD_MODULE_HEADER,
"hello",
hello_functions,
PHP_MINIT(hello),
PHP_MSHUTDOWN(hello),
PHP_RINIT(hello), /* Replace with NULL if there's nothing to do at request start */
PHP_RSHUTDOWN(hello), /* Replace with NULL if there's nothing to do at request end */
PHP_MINFO(hello),
PHP_HELLO_VERSION,
STANDARD_MODULE_PROPERTIES
};
暂时不用修改,知道这是一个入口即可。在本条目之后,我们继续了解如何向扩展添加方法。 hello_functions[] 方法数组中已经有一个示例方法confirm_hello_compiled。我们引用它来编写我们的方法 hello_world
const zend_function_entry hello_functions[] = {
PHP_FE(confirm_hello_compiled, NULL) /* For testing, remove later. */
PHP_FE(hello_world, NULL)
PHP_FE_END /* Must be the last line in hello_functions[] */
};
首先将hello_world添加到扩展方法数组中,然后定义hello_world。找到confirm_hello_compiled方法定义的地方,然后按照下面的操作。 php_printf 是 Zend Engine 中的 printf 方法。
PHP_FUNCTION(hello_world)
{
php_printf("Hello World!\n");
RETURN_TRUE;
}
编译安装
最后一步是编译并安装我们的扩展。安装了PHP扩展的同学无需阅读。没有经验的可以参考一下。
/usr/local/php/bin/phpize
./configure --with-php-config=/usr/local/php/bin/php-config
make
make test
make install
现在php扩展目录下已经有hello.so文件了,在php.ini中添加扩展配置
extension = hello.so
测试
编写一个test.php方法并执行脚本可以看到“Hello World!”