👻

php5.2.17→php7.4.33へ移行したメモ

2022/12/29に公開

php5.2.17のレガシーシステムをphp7.4.33へ移行した記録
8系はハードル高そうなので検討したが見送りした。

「php7cc」と言うphp5 → php7で廃止される関数やエラーになる部分を検知してくれる
アプリがあるようなのでまずはインストールして修正範囲を認識してエラーをつぶして行くと言う流れで行ってみる。

php7ccをcomposerでインストール

環境
Mac OS Monterey 12.6
MacBook Pro (13-inch, M1, 2020)

自身のローカル環境にインストールして検証していく

composerのインストールは省く

composer global require sstalle/php7cc

なんか心配になる文章が出てくるけど大丈夫なのかな?

Package sstalle/php7cc is abandoned, you should avoid using it. No replacement was suggested.
Package symfony/debug is abandoned, you should avoid using it. Use symfony/error-handler instead.

php7ccコマンドが打てる様にパスを通します(mac)

#シェルを確認
echo $SHELL
#zshなのでこのファイルを開く
open ~/.zshrc
#パスを書き加える
export PATH=$PATH:$HOME/.composer/vendor/bin
#反映させる
source ~/.zshrc

動いてくれた

検証対象のディレクトリを指定してコマンドを実行

php7cc /対象ディレクトリ/ > php7result.txt

誤検知もあるみたいだがとりあえず進めてみよう

エラー対応

テキストファイルに書き出されたエラーを潰していく作業のログ
まずは、一通り目を通してからやると効率が良い
https://www.php.net/manual/ja/migration70.php

[Warning] Function argument(s) returned by "func_get_args" might have been modified

パラメータを受け取った時点では無く最新の値が反映される様になった模様
https://www.php.net/manual/ja/migration70.incompatible.php#migration70.incompatible.other.func-parameter-modified

// これを
public function hoge(){
  $args = func_get_args();
}
// こう書き換える
public function hoge(...$args){
}

でも、受け取った直後に値変える様な処理はなさそうなので
今回は対応しなくてもいいかな?

https://medium-company.com/php-可変長引数/

staticなメソッドじゃないのに$thisを使っている所で出たエラー
親クラスを継承した子クラス内で$thisを使って親クラスのメソッドを呼んでいた。
親クラスをインスタンス化して解決したけど納得いかない。。

Fatal error: Uncaught Error: Using $this when not in object context in

https://reeedpanda.com/blog/php-static-error/

オーバーライド元と先で引数とか型が違うエラー
自分の場合は引数を元と合わせたらエラー解消

Warning: Declaration of  should be compatible

https://qiita.com/pappikko/items/24a104d7203be650739a

関数名は文字列でなければならないと言う趣旨のエラー

Possible array element creation during by-reference assignment

まさに参考記事の様にメソッド名を可変変数の配列で利用していた部分でエラーになっていた。

Class My_Class {
	public function mymethod() {
		echo 'test';
	}
}

$class_to_method = array(
	'class' => 'My_Class',
	'method'=> 'mymethod',
);

$instance = new $class_to_method['class'];
// エラーになっていた箇所
// $instance->$class_to_method['method']();

// 以下の様に配列では無い可変変数に入れ直してエラー解消
$method = $class_to_method['method'];
$instance->$method();

そして、得た答えは「可変変数でメソッドを実行する場合は、その可変変数は配列を直接参照してはならない」ということ。
http://www.cattlemute.com/2018/06/11/1027/

新しいオブジェクトを参照渡しで代入できないエラー
7からはデフォルトで参照渡しになるので&を削除するだけで良いみたい

// ブラウザで出たエラー
Parse error: syntax error, unexpected 'new' (T_NEW) in
// php7ccで出たエラー
[Error] Result of new is assigned by reference

https://www.php.net/manual/ja/migration70.incompatible.php#migration70.incompatible.other.new-by-ref

参照による代入で自動的に作成した配列要素の並び順の変更
順番が変わっても挙動に影響ないなら無視でおk

[Warning] Possible array element creation during by-reference assignment

https://www.php.net/manual/ja/migration70.incompatible.php#migration70.incompatible.variable-handling.array-order

ループじゃないとこでbreak使うとエラー

[Error] break not in the loop or switch context

https://www.php.net/manual/ja/migration70.incompatible.php#migration70.incompatible.variable-handling.array-order

switch文のdefault部分でcontinueが使われていたがphp7.3からは引数を指定しないと
breakと見分けつかないからエラーになるとのこと
continue 2と修正した

"continue" targeting switch is equivalent to "break". Did you mean to use "continue 2"? in

https://www.php.net/manual/ja/control-structures.continue.php
https://info-con.co.jp/tips/wordpress-21-search_replace_db-php_error/

PHP 4 形式のコンストラクタを修正
PHP 4時代はクラス名と同じメソッドでコンストラクタを作る形式だったのを__constructに修正

[Error] PHP 4 constructors are now deprecated
<?php
class foo {
    //function foo() {
    function __construct() {
        echo 'I am the constructor';
    }
}
?>

https://www.php.net/manual/ja/migration70.deprecated.php#migration70.deprecated.php4-constructors

preg_replace 関数の e 修飾子が使えなくなったエラー

[Error] Removed regular expression modifier "e" used

e修飾子を使うと、第2引数がPHPプログラムとして解釈されます。
しかしこれは見るからに脆弱性を生みそうなコードです。PHP 5からこの文法は非推奨になる、7で削除されることになりました。PHP 7にバージョンアップするに当たり、preg_replace_callback を利用して書き換える必要があります。

https://www.utakata.work/entry/20180101/1514811599#preg_replace-関数の-e-修飾子が使えなくなった

感想

思っていたよりは修正箇所が少なかったので安心した。
phpExcelがphp7.2から使えなくなり、phpSpreadsheetに移行しなければならない趣旨の記事が散見されたが不要なbreakをコメントアウトしたのみで自分の環境では動いているので用途によると思う。
自分の環境ではただPDF的な使い方しかしていないからかもしれない。

注意すべきは、php7ccは最新の7系に対応している訳ではない模様なので(7.1まで?)自身の手でもデバッグは必須なところ
https://www.utakata.work/entry/20181206/1544049000

参考リンク

https://www.php.net/manual/ja/migration70.php
http://blog.a-way-out.net/blog/2015/10/30/migration-to-php7/
https://tech.pepabo.com/2017/06/21/goope-php71-upgrade/
https://codezine.jp/article/detail/8952
https://it-afi.com/php/今さらphp7ccを使ったphp7化/
https://qiita.com/su_mi/items/b9f06a81bdae40b84c61
https://qiita.com/ProjectEuropa/items/08d0a43ee4e5a2734f79
https://qiita.com/sta/items/63e1048025d1830d12fd
https://amateur-engineer.com/mac-path-zsh/
https://tatsuya-koyama.com/notes/languages/php/
https://qiita.com/shizen-shin/items/3011ffb0aaa1edac4d0d
https://teratail.com/questions/163377
https://tech-blog.s-yoshiki.com/entry/210

Discussion