php /path/to/php/ext/ext_skel.php 生成扩展结构
上面 ext_skel.php 是 php >= 7.3 以前的版本是 php ext_skel
root@68555cf5182c:/home/www-data/php-ext/luff# tree.|-- config.m4|-- config.w32|-- include|-- luff.c|-- luff.stub.php|-- luff_arginfo.h|-- php_luff.h|-- test.php|-- tests| |-- 001.phpt| |-- 002.phpt| |-- 002.sh| |-- 003.phpt| `-- 003.sh`-- tmp-php.ini2 directories, 13 files
config.m4
autoconf 语法规则的编译配置文件,它可以指定扩展支持的 configure 选项以及扩展需要的额外库。包含哪些源文件等
phpize 根据 config.m4 生成 configure 等文件
dnl PHP_ARG_WITH(arg-name, check message, help text[, default-val[, extension-or-not]])# 注册扩展 ./configure 时试用方式# ./configure --with-luffPHP_ARG_WITH(luff, whether to enable luff support,AS_HELP_STRING([--enable-luff], [Enable luff support]))dnl PHP_ARG_ENABLE(arg-name, check message, help text[, default-val[, extension-or-not]])# 注册扩展 ./configure 时试用方式# ./configure --enable-luffPHP_ARG_ENABLE(luff, whether to enable luff support,AS_HELP_STRING([--enable-luff], [Enable luff support]))# 注册扩展if test "$PHP_LUFF" != "no"; thenAC_DEFINE(HAVE_LUFF, 1, [ Have luff support ])dnl PHP_NEW_EXTENSION(extname, sources [, shared [, sapi_class [, extra-cflags [, cxx [, zend_ext]]]]])PHP_NEW_EXTENSION(luff, luff.c, $ext_shared)fi
PHP_ARG_ENABLE宏: 第一个参数表示扩展名称;第二个参数在执行 ./configure 处理到该扩展时,显示该参数的内容;第三个参数是执行 ./configure —help 的输出信息。./configure 时会显示如下信息
...checking whether to enable luff support...
./configure --help 时会显示如下信息
...Optional Features and Packages:...--enable-luff Enable luff support...
运行 ./configure --enable-luff 命令 $PHP_LUFF 将设为 yes
PHP_NEW_EXTENSION 宏: 声明了扩展的名称、源文件列表(多个文件的时候在名称后边加空格,如果需要换行还需加上反斜杠 “\”)、次扩展是动态库还是静态库,扩展是否只能在 CLI 或 CGI 模式下运行等。
$ext_shared 参数用来声明这个扩展不是一个静态模块,而是在 php 运行时动态加载的。
创建函数
ZEND_FUNCTION
# 定义 php 函数# 函数实际处理方法ZEND_FUNCTION(function_name){php_printf("Hello PHP!");}// 把这个函数放到 zend_function_entry 数据结构里static const zend_function_entry luff_functions[] = {ZEND_FE(function_name, NULL)ZEND_FE_END};#define PHP_FUNCTION ZEND_FUNCTION#define ZEND_FUNCTION(name) ZEND_NAMED_FUNCTION(ZEND_FN(name))#define ZEND_NAMED_FUNCTION(name) void name(INTERNAL_FUNCTION_PARAMETERS)#define ZEND_FN(name) zif_##nameZEND_FUNCTION(luff) 实际在 c 语言中是这样的void zif_luff(INTERNAL_FUNCTION_PARAMETERS){// something}
其中,zif 是 zend internal function 的意思,zif_ 前缀是可供 PHP 语言调用的函数在 C 语言中的函数名称前缀。
zend_module_entry
/* {{{ luff_module_entry */zend_module_entry luff_module_entry = {STANDARD_MODULE_HEADER,"luff", /* Extension name */luff_functions, /* zend_function_entry */PHP_MINIT(luff), /* PHP_MINIT - Module initialization */PHP_MSHUTDOWN(luff), /* PHP_MSHUTDOWN - Module shutdown */PHP_RINIT(luff), /* PHP_RINIT - Request initialization */PHP_RSHUTDOWN(luff), /* PHP_RSHUTDOWN - Request shutdown */PHP_MINFO(luff), /* PHP_MINFO - Module info */PHP_LUFF_VERSION, /* Version */STANDARD_MODULE_PROPERTIES};/* }}} */
PHP_MINFO 注册用于 php --ri luff 或 phpinfo() 命令时输出的信息
编译
我们需要根据 config.m4 文件生成一个configure 脚本、Makefile 等文件,这一步由 phpize 来帮我们做
phpize 程序根据 config.m4 里的信息生成了许多编译 php 扩展必须的文件,比如生成 Makefile 等,这为我们省了很多的麻烦。
phpize./configuremakesudo make install
加载
为了使 PHP 能够找到需要的扩展文件,我们需要把编译好的 so 文件或者 dll 文件复制到 PHP 的扩展目录下,它的地址我们可以通过 phpinfo() 输出的信息找到,也可以在 php.ini 文件里进行配置找到并配置,名称为: extension_dir 的值。默认情况下,php.ini 文件位于 /usr/local/lib/php.ini。如果找不到,我们可以通过 php -i 命令或者 <?php phpinfo(); 来查看当前加载的 php.ini 文件位置。 一旦我们设置了 extension_dir,便可以在我们的 web 文件中引用我们的扩展了,我们可以通过 dl 命令来将我们的扩展加载到内存中来。
<?phpdl('sample.so');var_dump(get_loaded_extensions());
上面这样每次使用扩展都需要先dl一下真是太麻烦了,其实我们有更好的办法让php运行时自动加载我们的扩展。那就是在php.ini里这样配置:
extension_dir=/usr/local/lib/php/modules/extension=walu.so
这样只要我们把walu.so这个文件放置在extension_dir配置的目录下,php就会在每次启动的时候自动加载了。这样我们就可以像我们平时使用curl、Mysql扩展一样直接使用,而不用麻烦的调用dl函数了
