php7.4扩展
php 的底层是由 c/c++ 实现的,所以 php 本身就是一层皮,而我们也可以通过开发一些扩展来增强 php。可以通过 php -m
或 phpinfo()
来查看环境中已安装的扩展,目前最新的 php 版本为 7.4.6 ,所以直接以 php7.4 为例。
查看 php 版本
因为本地的 php 运行环境是通过 docker 起的,这里也安利一波 laradock 环境模板,本地的测试环境用起来实在是很舒服,又很自由。
$ docker-compose exec workspace bash // 非 laradock 忽略
$ php -v
PHP 7.4.0 (cli) (built: Nov 28 2019 07:26:50) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
with Zend OPcache v7.4.0, Copyright (c), by Zend Technologies
这边确认一下自己的 php 版本确实为 7.4。
下载源代码
我们需要下载 php 的官方源码,选择自己对应的版本。
$ curl -O https://www.php.net/distributions/php-7.4.6.tar.bz2
也可以通过官网去获取,www.php.net,锁定自己的大版本即可,例如 7.2、7.3、7.4。
解压源码
$ tar -jxvf php-7.4.6.tar.bz2
生成扩展
进入源码目录下 ext 目录,可以下面有个 ext_skel.php
文件,该文件是用来生成扩展工程的脚手架命令。
$ cd ext
$ php ext_skel.php --ext foobar
Copying config scripts... done
Copying sources... done
Copying tests... done
Success. The extension is now ready to be compiled. To do so, use the
following steps:
cd /path/to/php-src/foobar
phpize
./configure
make
Don't forget to run tests once the compilation is done:
make test
Thank you for using PHP!
foobar 为扩展名称,foobar 文件夹就是骨架工程了,对于 php7 是不需要对 php_foobar.h 和 foobar.c 文件做任何其他变更,可以直接添加自己需要的函数。
打开 foobar.c 找一个有利的位置添加以下代码:
PHP_FUNCTION(hello)
{
php_printf("hello world2");
}
其实模仿上下的 foobar_test1 foobar_test2 也就大概知道放在什么位置了,PHP_FUNCTION 函数上下的注释目前我也不知道有啥用,经测试不影响代码运行。
static const zend_function_entry foobar_functions[] = {
PHP_FE(hello, NULL ) // 增加这一行
PHP_FE(foobar_test1, arginfo_foobar_test1)
PHP_FE(foobar_test2, arginfo_foobar_test2)
PHP_FE_END
};
第一个参数为函数名,第二个为函数参数吧(暂不确定)。
编译安装
$ phpize
$ ./configure
$ make
一坨一坨输出飞过,留下了一个 so 文件,modules 文件夹下可以看到这个产物,如果 php 运行环境和上面的扩展生成环境是一样的,执行 make install
,会将 so 文件移动到 php 扩展的默认文件路径下。如果像我一样,他们不是一个环境也没有关系。
ini 添加扩展
打开 php.ini 配置文件最下面添加一行
extension=foobar.so // make install 之后可以直接填写扩展的文件名 OR
extension=/var/www/phpext/ext/foobar/modules/foobar.so // 其实也可以写绝对路径
代码调试
- cli 环境可以执行
php -r "hello();echo PHP_EOL;";
- cgi 环境可以在代码中执行 hello();
都可以看到最终 "hello world2" 输出,这就是通过 c 代码编写的输出结果。
总结
只是一个练手项目和什么 pdo gd 类的扩展那不是一个层次的。有了扩展开发就能调用更底层的系统接口,和更复杂的计算型任务。