php7.4扩展开发

php 的底层是由 c/c++ 实现的,所以 php 本身就是一层皮,而我们也可以通过开发一些扩展来增强 php。可以通过 php -mphpinfo()来查看环境中已安装的扩展,目前最新的 php 版本为 7.4.6 ,所以直接以 php7.4 为例。

查看 php 版本

因为本地的 php 运行环境是通过 docker 起的,这里也安利一波 laradock 环境模板,本地的测试环境用起来实在是很舒服,又很自由。

1
2
3
4
5
6
7
$ 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 的官方源码,选择自己对应的版本。

1
$ curl -O https://www.php.net/distributions/php-7.4.6.tar.bz2

也可以通过官网去获取,www.php.net,锁定自己的大版本即可,例如 7.2、7.3、7.4。

解压源码

1
$ tar -jxvf php-7.4.6.tar.bz2

生成扩展

进入源码目录下 ext 目录,可以下面有个 ext_skel.php 文件,该文件是用来生成扩展工程的脚手架命令。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
$ 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 找一个有利的位置添加以下代码:

1
2
3
4
PHP_FUNCTION(hello)
{
php_printf("hello world2");
}

其实模仿上下的 foobar_test1 foobar_test2 也就大概知道放在什么位置了,PHP_FUNCTION 函数上下的注释目前我也不知道有啥用,经测试不影响代码运行。

1
2
3
4
5
6
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
};

第一个参数为函数名,第二个为函数参数吧(暂不确定)。

编译安装

1
2
3
$ phpize
$ ./configure
$ make

一坨一坨输出飞过,留下了一个 so 文件,modules 文件夹下可以看到这个产物,如果 php 运行环境和上面的扩展生成环境是一样的,执行 make install ,会将 so 文件移动到 php 扩展的默认文件路径下。如果像我一样,他们不是一个环境也没有关系。

ini 添加扩展

打开 php.ini 配置文件最下面添加一行

1
2
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 类的扩展那不是一个层次的。有了扩展开发就能调用更底层的系统接口,和更复杂的计算型任务。

参考文档

坚持原创技术分享,您的支持将鼓励我继续创作!