升級 PHP7 過程記錄

caohaoyu發表於2019-02-27

一、背景

專案一直處於PHP5.6的執行環境中,決定將PHP升級到PHP7,考慮的原因主要包括:

1、PHP7的正式版也已經發布了很長時間,就穩定性和資料的豐富程度來說都足夠了

2、看到PHP5.*的不會進行安全維護的通知

3、PHP7相對PHP5的效能相關有提升

4、生命不息,折騰不止

特此將升級過程及步驟進行記錄,希望可以幫到有類似需求的小夥伴!

二、安裝PHP7

這個步驟就不多說了,從網上查詢下安裝過程,按照教程進行即可。(ps:公司的伺服器上已經有其他同事安裝過了,我直接使用就好了)

php7和php5.6具體資訊:

# php7 -v
PHP 7.1.12 (cli) (built: Jun  8 2018 19:36:50) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

# php -v
PHP 5.6.10 (cli) (built: Jun  8 2018 14:46:07) 
Copyright (c) 1997-2015 The PHP Group
Zend Engine v2.6.0, Copyright (c) 1998-2015 Zend Technologies

三、專案使用PHP7環境

測試環境上執行的專案有很多,所以不能直接將預設的php替換成PHP7,採用的方式是使用nginx配置進行處理,設定這個專案使用phpfpm7。

呼叫專案中的測試介面,測試介面內容:echo phpinfo(); 可以觀察到已經替換為PHP7了!

四、靜態程式碼檢測

眾所周知,PHP7廢除了很多函式,所以我們需要對程式碼進行檢測專案的相容性。

採用的方法是利用 PHPCS和PHPCompatibility 對專案進行PHP7的編碼規範檢測。

//PHPCS和PHPCompatibility安裝和使用流程
mkdir /tmp/php_codesniffer 
curl -s http://getcomposer.org/installer | php 
./composer.phar config -g repo.packagist composer https://packagist.phpcomposer.com 
./composer.phar selfupdate 
./composer.phar require "squizlabs/php_codesniffer=*" 
cd /tmp/PHPCompatibility 
git clone https://github.com/wimg/PHPCompatibility.git 
/tmp/PHPCompatibility/vendor/bin/phpcs --config-set installed_paths /tmp/PHPCompatibility/PHPCompatibility/ 
/tmp/PHPCompatibility/vendor/bin/phpcs -i 
/tmp/PHPCompatibility/vendor/bin/phpcs --standard=PHPCompatibility --report-file=/tmp/check_php7_report [專案路徑] 

之後就可以根據生成的報表'/tmp/check_php7_report',逐條對專案程式碼進行處理了。

五、錯誤日誌哪去了?

專案使用的是ThinkPHP3.2.2框架,但是到目前為止,仍未找到錯誤日誌輸出到哪裡了,之後有時間再繼續進行吧,大概流程如下:

1、首先在nginx中增加如下配置:
error_log logs/error.log error;
然後經過幾天的使用,從未看到有過日誌記錄,認為沒有出現問題。

2、突發奇想,想驗證下錯誤情況是可以被記錄的,於是寫了個介面,具體內容:

 $str = 'asdasdaiAAS';
 echo preg_replace("/([A-Z])/e", "'_' . strtolower('\\1')", $str);

在Linux下執行PHP指令碼輸出以下內容,同理介面也應該返回同意內容:
php5.6 : asdasdai_a_a_s
php7   :PHP Warning:  preg_replace(): The /e modifier is no longer supported, use preg_replace_callback instead in ..

3、但是實際情況,在PHP5.6介面返回與預期符合,但是在PHP7直接返回空並且httpcode為200(問題出現)

4、初步猜測是由於ThinkPHP框架導致未記錄錯誤情況,所以檢視其配置及框架的日誌,均未發現異常。

5、未完待續,等有時間再查下錯誤日誌去哪了

六、介面檢測

本來是想透過錯誤日誌來確認介面是否存在問題的,但是由於找不到錯誤日誌,所以無奈下換另外的方案:

1、透過nginx的日誌獲取呼叫過的介面,然後跟專案所有介面去重,找到未呼叫的介面

2、呼叫過的介面使用指令碼分別在PHP5.6和PHP7的環境下重新呼叫獲取返回值,把兩次的返回值md5加密後進行對比

有了方案後處理起來並不難,按照預期應該是一致的,但是確實存在問題了!(從側面也說明這個介面檢測是很有必要的,不能僅靠測試人員在功能上驗證)

七、發現的坑及填坑方法

1、問題:php7的json_encode處理float型別會出現溢位的現象

php5.6:[6.28] 
php7:[6.2800000000000002] 

解決方案:修改php.ini中serialize_precision 到17以下,自測php7恢復正常

2、問題:在命令列解決了json_encode溢位問題,然後介面還是會存在問題

解決方案:重啟PHP7的phpfpm

3、問題:php7的計算中,如果除數為0會導致結果為NAN

php5.6:0 
php7:NAN

解決方案:判斷下除數為0的情況

八、結語

這次升級PHP7的工作還沒有結束!目前只是完成自測部分,等待測試透過後,完美上線才能算收工大吉!

如果後續還有發現坑,會及時更新在這邊的。

希望可以前路坦蕩,一路無坑嘍~

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章