项目从PHP5.5切换到PHP7.1.15背景从鸟哥2015年的技术分享中我们知道PHP7是对底层实现的彻底重构,有很多便利比如函数调用机制和内存管理经过优化,PHP的性能有了很大的提升。迄今为止,PHP7经历了数次版本迭代。常用的扩展和插件基本兼容PHP7,升级PHP7的难度越来越低。随着闪贷业务的快速发展,推广业务和API接口的代码越来越复杂,页面响应时间也越来越慢,一定程度上影响了用户的访问体验。因此,近期花费了大量精力优化网站性能,力求给用户更好的体验。作为重要环节之一,升级PHP7已经取得了不小的成绩。后端Web服务器的负载和核心页面的响应时间都大大降低了。PHP代码升级从PHP官方升级文档来看,PHP7的语法相比PHP5基本变化不大,实现了99%的向后兼容。但是项目中还是有很多不规范的编码或者使用建议废除的函数导致的不兼容,使用的ThinkPHP3.1框架也有很多不兼容的地方:preg_replace的e修饰符弃用,改用preg_replace_callback函数,例如:preg_replace("/_([a-zA-Z])/e","strtoupper('\\1')",$名称);替换为preg_replace_callback('/_([a-zA-Z])/',function($r){returnstrtoupper($r[1]);},$name)eregi函数的弃用,使用preg_match函数使用/i修饰符来替换ereg函数。使用同名的preg_match类名和方法名将被解析为构造函数。PHP7以后会报错。__construct替换方法中没有必需的参数。传说PHP5会报警告,但是项目会继续执行,而PHP7会直接报错终止程序。运行PHP7对间接变量的解析顺序与PHP5不一致。如果要保持一致,使用{}来保证解析顺序$foo->$bar['baz']//解释为($foo->$bar)['baz']替换为$foo->{$bar['baz']}$foo->$bar['baz']()//解释为($foo->$bar)['baz']()替换为$foo->{$bar['baz']}()Foo::$bar['baz']()//解释为(Foo::$bar)['baz']()替换为Foo::{$bar['baz']}()使用php7cc辅助进行代码检查,php7cc可以检查出项目中大部分代码不兼容的情况,然后逐个文件输出到文本中进行兼容性处理。也可以访问项目打包测试流程进行代码测试。扩展替换PHP7后,mysql和mongo扩展被丢弃。项目中ucenter使用的db类使用废弃的mysql扩展,msyqli扩展作为兼容替代。因为mongo扩展在项目中使用过多,而且完全不兼容mongodb扩展API,如果切换必须重写整个底层访问接口,工作量太大,所以mongo-php-adapter使用的,是基于ext-mongodbAPI编写的ext-mongoadapter,无需修改代码即可迁移到ext-mongodb,迁移成本低很多。测试计划与大多数公司的类似。项目组划分三个环境:线下开发环境、预发布环境和生产环境。一个需求从开发到上线一般会经历几个步骤:工程师在统一的离线开发环境中完成开发和简单的测试;然后部署到预发布环境,测试人员进行统一测试和回归;最后,正式部署到生产环境。我们在升级部署PHP7的时候,也是按照这个顺序进行的:升级离线开发环境,包括扩展升级和代码升级,测试;升级预发布环境,测试;灰度测试生产环境,抓取错误日志分析,稳定运行一段时间,再全面升级生产环境。
