为什么要开发PHP扩展
PHP-X是用来开发PHP扩展的库。PHP代码写得好好的,为啥要开发PHP扩展呢?
1、我们知道PHP不擅长CPU密集型的操作,那么把CPU密集型的相关代码迁移到扩展上,就可以大幅提高效率了,比如加密mcrypt、序列化igbinary、图像处理gd2等。
2、另外有些系统相关的操作,PHP没有提供接口,那么也可以通过扩展开提供,比如多进程PCNTL、多线程Pthread、文件事件inotify等。
3、追踪PHP的调用,为代码优化提供建议,比如各种监控APM。
大牛们说的从用户空间沉降到内核空间,就是指从PHP代码改为扩展。
开发扩展用的语言
PHP的解释器ZendEngine提供了一些列C接口,可以用C、C++语言来开发接口。
由于扩展都是以动态库的形式提供,理论上能生成动态库并符合Zend接口的语言都可以,比如有人就用Rust来开发PHP扩展。
另外还可以用Zephir,专门用来开发PHP扩展的语言,著名的Phalcon就是用Zephir开发的。
使用C/C++开发扩展的姿势
使用Zend提供的API来开发接口,实际上并不是很方便,具体的流程可以看这篇[教程](
http://www.php-internals.com/book/?p=chapt11/11-02-00-extension-hello-world)。
那么我们怎么开发呢?使用PHP-X,它是Swoole作者开源的,封装了Zend的API,
可以方便的使用CC++来开发PHP扩展。
安装PHP7
PHP-X只支持PHP7以上,这里我们使用PHP7.1来开发,测试发现PHP7.2暂时还不支持。
下面我们将在centos7环境上进行,你可以选择自己喜欢的Linux系统。
自发现了remi源里面有各种PHP相关的软件包,我就变懒了,不再手工编译了。
1.先安装remi源 ,网址
yum install -y https://mirrors.tuna.tsinghua.edu.cn/remi/enterprise/remi-release-7.rpm
2.编辑remi配置 vi /etc/yum.repos.d/remi-php71.repo 打开PHP7.1
3.安装PHP以及开发PHP的开发库
yum install php php-devel -y
4.安装cmake、gcc等
yum install cmake3 make gcc gcc-c++ git -y
5.编译PHP-X
先下载PHP-X的代码,git clone https://github.com/swoole/PHP-X
进入PHP-X文件夹
cmake .
make -j 4
sudo make install
可以看到如下输出:
libphpx.so被安装到了/usr/local/lib下
6.测试
进入example/cpp_ext 目录下
make install
会自动把生成的cpp_ext.so复制到PHP的扩展目录。
这时可以修改php.ini,remi源使用的是php.d文件夹中的ini,即每个扩展独立的配置,这种做法比修改完整的php.ini更好。
我们也采用这种方式。
下查看一下配置目录,如下:
然后新建cpp_ext.ini,内容为:
extension=cpp_ext.so
复制 cp cpp_ext.ini /etc/php.d/
运行 php -m | grep cpp_ext
如果有输出,则安装成功。
如果出现下面的错误,表示libphpx.so动态库没找到,我们需要配置一下动态库的加载路径。
使用ldd查看一下cpp_ext.so,确实没找到libphpx.so。
配置动态库加载路径
- 先查看环境
echo $LD_LIBRARY_PATH
变量,如果输出为空,则配置为export LD_LIBRARY_PATH=/usr/local/lib/
,
如果不为空,则export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/local/lib/
- 刷新环境变量
source ~/.bashrc
- 刷新动态库缓存
lddconfig
更多的文档可以参考作者在PHPCon China 2017上使用C++开发PHP7扩展 的演讲(PS:网页上还有有其它演讲者的ppt,值得一看,或者在这里下载)以及官网文档。
扩展
我们看到使用PHP-X编写的扩展库,并不能独立运行,还需要libphpx.so才行。那么可以做到扩展独立吗?
熟悉CC++的人知道,库分为动态库,和静态库。如果编译的时候把PHP-X编译为静态库,并采用静态链接的方式,就可以把我们的自己编写的扩展独立于libphpx.so了。
独立的好处在于部署方便,发布后用户就不用额外依赖PHP-X了;坏处在于如果都使用PHP-X,就造成了代码冗余。
另外类似PHP-X的还有国外的PHP-CPP。