本文将会基于PHP7开发一个最简单的扩展,随便取个名learn_ext,编译生成一个learn_ext.so文件,最终调用可以在php中调用learn_ext扩展中的函数来输出一个hello world,并且可以在phpinfo()中看到learn_ext展信息。
开始之前
- 你需要有PHP和C语言/C++基础
- 掌握Linux下编译安装PHP
- 本次使用PHP7.4进行扩展开发
- 在Linux上安装PHP7.4环境
- 根据你的个人习惯,使用Centos、Ubuntu或其它系统均可。
参考资料:
下载PHP源码包
下载源码包:
1 | wget https://www.php.net/distributions/php-7.4.4.tar.gz |
如果下载速度太慢,可以使用国内的地址:
1 | wget https://share-disk-1252104623.cos.ap-guangzhou.myqcloud.com/php-7.4.4.tar.gz |
下载完成后,解压源代码,进入源代码的扩展目录:
1 | tar zxvf php-7.4.4.tar.gz |
生成扩展开发的基本骨架
在扩展目录(ext)中,有一个ext_skel.php
脚本,可以用于生成扩展开发的基本骨架。这个脚本是用PHP编写的,因此你需要提前安装好PHP环境。
执行脚本php ext_skel.php --help
可以看到说明和常用参数。对于初学者来说,只需要了解--ext
这个参数就够了。
创建一个叫做learn_ext
的扩展:
1 | php ext_skel.php --ext learn_ext |
顺利的话,会看到扩展开发的一些提示:
Copying config scripts… done
Copying sources… done
Copying tests… doneSuccess. The extension is now ready to be compiled. To do so, use the
following steps:cd /path/to/php-src/learn_ext
phpize
./configure
makeDon’t forget to run tests once the compilation is done:
make testThank you for using PHP!
这个操作会在ext/目录下生成一个learn_ext目录,查看learn_ext目录中的文件如下:
1 | config.m4 |
我们主要关注的文件是learn_ext.c
,这是扩展的源代码文件。在这个文件中,已经有两个函数的例子写在learn_ext.c
里面了。
第一个函数:
1 | /* {{{ |
从注释中可以看出这个,函数原型是void learn_ext_test1()
,一个没有参数也没有返回值的函数learn_ext_test1
,函数运行后将会打印一句话:The extension learn_ext is loaded and working!
。
第二个函数
1 | /* {{{ string learn_ext_test2( [ string $var ] ) |
同样,注释中标注了函数原型是string learn_ext_test2( [ string $var ] )
,即参数是一个字符串类型的可选参数,返回值也是一个字符串。
从源代码可以看出来,这个函数会返回Hello %s
,其中%s
是参数var
。var
参数是可选的,如果没有传入参数,则使用默认值char *var = "World";
,最后返回字符串Hello World
。
编译扩展
根据上面创建扩展骨架时的提示:
The extension is now ready to be compiled. To do so, use the
following steps:cd /path/to/php-src/learn_ext
phpize
./configure
make
按照提示中的流程,进入到learn_ext
扩展目录,使用phpize
命令编译扩展:
1 | root@ed78d89e5328:~/php-7.4.4/ext/learn_ext# phpize |
检查并生成编译配置:
1 | ./configure |
编译扩展:
1 | make |
很快,编译完成。顺利的话,在learn_ext扩展目录下的modules目录,会生成一个learn_ext.so
,这个就是最终生成的扩展二进制文件。
安装扩展
编辑PHP配置文件php.ini
,增加一行扩展配置:
1 | extension=/root/php-7.4.4/ext/learn_ext/modules/learn_ext.so |
测试扩展是否生效
以下几种方法都可以验证扩展是否安装成功:
不用重启PHP,使用
php -m
命令打印已安装的扩展,可以找到learn_ext
说明扩展安装成功。1
2root@ed78d89e5328:~# php -m |grep learn_ext
learn_ext创建一个PHP脚本
test.php
,可以调用扩展里面的方法:1
2
3
4
5
6
7
learn_ext_test1();
echo "\n";
echo learn_ext_test2();
echo "\n";
echo learn_ext_test2("learn_ext");
echo "\n";保存后,执行
php test.php
, 输出:The extension learn_ext is loaded and working!
Hello World
Hello learn_ext查看phpinfo():
1
2
3root@ed78d89e5328:~# php -r "phpinfo();"|grep learn_ext
learn_ext
learn_ext support => enabled如果是在网页中查看phpinfo, 需要重启php-fpm或nginx/apache。
下一步
以上就是扩展开发和安装的流程。
接下来,了解函数的组成部分:
Linux下PHP7扩展开发入门教程2: 函数结构详解