本文内容简介
- 简要介绍本博客写作背景和目的:升级PHP Native Interface的代码使其支持PHP7。
- PNI 升级以支持PHP7的过程做简单介绍。
- 对这次升级的思路和方法进行总结。
- 思维发散,假设其他情况下应该用什么样的方法进行升级php7的扩展。
背景和目的
PNI在2016年10月之前仅支持php5系列的版本。9月份时进行升级,使其支持PHP7。
PNI是什么? 具体参考这边博文《PHP Native Interface》。PNI代码规模只有1000行左右,升级大概花费了一周时间(工作外时间),其中包含2天寻找思路、2天的代码升级,3-4天的问题排查。
这篇博客记录了一下PNI升级过程,包括自己学习PHP7扩展框架、API定义的过程,调试、压测、修复bug的过程等。
把这些东西记录下来,主要是为了总结出自己的学习方法和操作方法。写成博客后,可以更好地帮助自己反思升级过程中是否有哪些不好的地方。当然其中也会有自己的成功经验。
PNI 升级过程简述
面临哪些问题,以及有哪些不确定的地方?
- 代码从何处改起?
- 如何保证编译通过?
- 功能能否保证不变,以及PNI自身定义的PHP接口是否需要发生变化。
- 升级过程中遇到bug和陷阱怎么办?
- 这次升级的代价有多大?
升级PNI,从哪入手?寻找突破点的过程。
用搜索引擎搜到了几篇博客,都是介绍PHP7和PHP5的 zend api 不同的网文。随意浏览了一下,感觉帮助不是特别大。
自己下载了PHP7.0的源代码,编译一下,稍微看了一下 Zend的源码(主要看Zend_API、zend_list、zend_hash),少数几个ext里的扩展的源码。
看了后收获特别大, 了解了 php7扩展编写的几个特点:
- php7 ext 扩展编写框架结构变化小
- API函数名称变化小,多数无变化
- API函数参数列表变化大
- 宏的变化小
升级的思路就有了。
升级方法?
依据发现的php7扩展代码的特点,决定以PHP5版本的PNI的代码为基础,进行升级。代码不需要做太大的变动,更不需要完全重写。
设立3个目标,并按顺序分步骤实现。 1. 升级代码,编译通过。 2. 功能验证通过。 3稳定性验证通过。
为了达到第一个目标,使编译通过,使用下面方法:
-
参考其他extention,首先对比php7和php5扩展的框架,优先修改PNI的框架。
-
对比PHP7 源码中的zend_API.h、zend_list.h、zend_hash.h等。
-
要修改的函数多,可能会有API没有升级被遗忘怎么办? 所以一边升级代码,一边make,看着gcc的错误提示去一点一点改正代码。
达到第2个目标的方法,则多写功能验证的测试case。
达到第3个目标的方法,是做压力测试,观察内存和cpu的使用情况。
- 观察变量和资源是否被及时回收,是否有内存泄漏
- 观察cpu负荷是否过高
在升级过程中遇到过最大的一个问题是,pni中遇到了内存泄漏。为了定位内存泄漏的原因,花了非常多的时间。
- 打日志,定位内存泄漏逻辑。
- 定位后,添加efree、free等函数调试。
- 添加efree逻辑无效,打印对象引用计数的个数
- 找到原因,是存储资源类型的变量,作为另一个对象的属性时,如果对象释放,存储资源类型的成员变量不会主动释放。
- 解决办法,在对象释放的析构函数中,添加释放资源的逻辑。
总结
总体上说,这次升级PNI比较顺利。
在做的过程中,思路其实并没有上面写的那么清楚,心中也只有个大概思路。
在刚开始时,寻找从何下手的过程中,还是走了一点弯路,但浪费的时间不多。
走的最大的弯路则是,上文说的定位和解决pni内存泄漏的过程中, 没有首先想到去观察对象或变量的引用计数的。这使pni升级的过程直接阻塞了。今后遇到内存泄漏的情况,应该首先观察zval的引用计数数目是否为0.
思维发散
下面开始做各种假设,假设我会面临不同的情况(实际并不存在),我该设计什么样的思路和方法进行PNI的升级呢?
-
假设PHP7和PHP5扩展开发的框架和结构有大的不同,对PNI的升级,完全重写也许是好方案。
-
PNI的代码规模只有1000行,假设10W行规模以上,我在达到上文说的,第1个编译通过的目标,就不能直接用gcc的错误信息去定位没有升级的代码,不能用一边改代码一边查php7 zend api代码。应该把PHP7的代码都给熟悉了,再去升级代码。
-
假设升级代码规模大,php7的扩展框架和代码与php5也有大不同呢?学习成本和工程量将变得非常大,这种情况怎么做呢? 1.大规模的代码,逻辑上应该做好分层和抽象。 在升级大规模代码前,应该先写一个小的PHP7扩展,拿来练手,这样学习的曲线就会平缓很多。
虽然看不懂捧个人场
欢迎光临, 以后常来我的博客留言呀!嘿嘿
程哥要坚持写呢
嗯嗯,一定会哒,一定不辜负您对我的期望
程哥,来交换交换友情链接哈。
http://findbug.site/
好呀,嘿嘿