背景php
從2015年鳥哥的技術分享,咱們知道PHP7是對底層實現得一次徹底重構,函數調用機制和內存管理等不少方便作了優化,使PHP性能有了很大的提高,至今PHP7經歷了多個版本的迭代,經常使用的擴展和插件也基本作到兼容了PHP7,升級PHP7的難度愈來愈低。mysql
隨着閃貸業務的快速發展,推廣業務和API接口的代碼變得愈來愈複雜,頁面響應時間變得愈來愈慢,必定程度上影響到用戶的訪問體驗。所以最近花費了不少精力在優化網站的性能上,力求使用戶獲得更好的體驗。升級 PHP 7 做爲其中一個重要環節,取得了可觀的效果,後端 web 服務器的負載和核心頁面的響應時間都下降了不少。web
PHP代碼升級sql
從PHP官方升級文來看,PHP7相較於PHP5語法基本改變不大,作到了向後99%的兼容,可是項目中仍是有不少編碼不規範或者使用建議廢除的函數致使的不兼容,使用的ThinkPHP3.1框架也有不少不兼容的地方:mongodb
preg_replace的e修正符的棄用,使用preg_replace_callback函數替代,例如:後端
preg_replace("/_([a-zA-Z])/e", "strtoupper('\\1')", $name);
替換爲
preg_replace_callback('/_([a-zA-Z])/', function($r) {return strtoupper($r[1]);},$name)
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
擴展替換框架
PHP7之後廢棄了mysql和mongo擴展,項目中使用的ucenter使用的db類使用的是已經廢棄的mysql擴展,使用msyqli擴展作兼容替換。函數
由於mongo擴展在項目中使用太多,並且和mongodb擴展的API一點都不兼容,如果切換必須重寫整個底層訪問接口,工程量太大,因此使用了 mongo-php-adapter,它是基於 ext-mongodb 的 API 寫的 ext-mongo 的適配器,能夠不對代碼進行任何修改,就遷移到 ext-mongodb 上,遷移成本低了不少。
測試方案
和大部分公司差很少,項目組劃分了線下開發環境、預發佈環境和生產環境三個環境。一個需求從開發到上線,通常通過幾個步驟:工程師在統一的線下開發環境完成開發和簡單的測試;再部署到預發佈環境,由 測試進行統一的測試和迴歸;最後,再正式部署到生產環境上。咱們在升級部署 PHP 7 時,也是按這樣的順序遞進的: