β

用php-x写php扩展

鱼儿的博客 223 阅读

最近工作中碰到了php扩展开发的需求,所以做了一些相关的学习,在此把碰到的问题简单记录下来。

需求来源

本次开发的目标是『调用链trace系统的sdk』,之前的代码是php代码实现的,对性能影响较大,影响了接口的处理能力,所以考虑改为扩展实现。

另外,php的进程模型是fpm,每次请求执行结束就释放了所有资源,因此只能通过扩展来实现常驻内存的设计。

制定目标

将现有sdk迁移至php扩展实现,同时php升级至php7。

准备工作

我对PHP扩展开发是0基础,但是有c/c++功底,这是开发php扩展的必要前提。

为了快速了解php扩展的原理,我快速的扫了一下这个教程:《 PHP扩展开发及内核应用 》,对PHP扩展的知识体系有了初步认识。

在后续开发中,实际发现PHP7的Zend api有不少重要的调整,因此又回头读了一遍官方发布的《 升级至PHP7 》,大概了解PHP7的主要数据结构和接口变化。

PHP-X

开发php扩展需要用到zend api,也就是php的核心类库,它是c语言实现的,然而zend api真的非常庞杂,不同的数据结构对应若干长相类似的函数,又对应着若干宏定义来简化函数,初次接触上手难度还是挺高的。

好在已经有开源项目把这些数据结构进一步封装成C++的类,并提供非常简单友好的类方法操作数据,我这里使用的『 php-x项目 』,他是swoole项目的作者开源的,对php扩展开发有丰富经验。

另外一个重要意义在于,php-x通过封装可以让我们更加系统的学习zend api,算是一本教科书。

你可以下载《 韩天峰——使用C++开发PHP7扩展.pdf 》来快速的了解PHP-X项目,是个很有想法的项目。

启动项目

下载php-x代码成功编译后,可以将 examples/cpp_ext 项目作为模板,启动你的扩展开发工作。

因为扩展是c/c++编写的,所以难免有内存忘记释放或者重复释放等问题,所以一定要重新编译你的php7,开启它的debug模式(–enable-debug)。

另外如果php7开启了Opcache,一定要配置php.ini添加如下配置,当扩展试图修改来自zend解释器的内存时会报错:

; Protect the shared memory from unexpected writing during script execution.
; Useful for internal debugging only.
opcache.protect_memory=1

另外,记得配置php.ini让其加载你的扩展so。

迭代方式

为了可以随时验证扩展是否正常工作,需要做好2件事情:

扩展通常会遇到2类内存问题,追查的方式不同:

根据我的经验,为了尽量减少排错耗费的时间和精力,在编写扩展时应该步步为营,即采用MVP(最小可用产品)原则,每开发完一小块逻辑单元,就重新编译扩展并执行php脚本进行验证,如果报错那么一定说明是最近添加的代码引起,排错就很简单了。

debug方法

如果你已经遵循MVP原则开发扩展,但是仍旧无法定位内存报错发生在哪个环节,可以采用2种方法:

除了内存问题,极有可能需要使用GDB跟踪代码执行来分析问题。

php-x项目使用了c++11,因此要求gcc > 4.8,在实际gdb跟踪项目的时候遇到了2个问题,大家应该也会遇到。

  1. 找不到扩展的源代码:因为gdb挂载的是php自身,再由php自身去加载扩展so,所以默认gdb只能break断点到php自身的源代码路径,找不到我们的扩展代码在哪里。需要在gdb中通过dir命令指定一下扩展的项目路径,指定后需要执行一次脚本,也就是在gdb中r test.php,这样php会加载一次我们的扩展so并根据dir指定的路径将对应的代码找到,此后就可以break断点到扩展源代码了。
  2. 看不到局部变量:通过bt命令虽然可以看到调用堆栈,但是p打印变量或者info locals都看不到任何变量具体内容。这是由于gcc4.8+引起的一个问题,需要在编译扩展时携带额外的参数(-gdwarf-2),具体可以参考《 c++ debugging with gdb 》。

如果对Zend api不熟悉,导致问题难以排查,那么给你2个思路:

php-x的问题

在使用php-x过程中,我有几个感受:

我认为后2个问题倒不是最重要的,只要公司的研发团队有能力处理也问题不大。

第2个问题是我比较头疼的,这需要了解到作者当初的设计思路,才能知其然之气所以然。

我认为既然采用c++11,那么可以考虑把move语义用起来,将拷贝和移动行为明确的分割开来设计,对资源引用计数提供一个更可信赖的机制,目前我对zend api了解还不够深入,也只能等待和作者交流一下思想了。

大家有PHP-X和扩展开发的问题,欢迎留言交流。

作者:鱼儿的博客
斯是陋室,惟吾德馨
原文地址:用php-x写php扩展, 感谢原作者分享。