かなり今更だが、今さらphp7ccを使ったphp7化(php7対応)のやり方をメモしておく。
php7ccインストール
まずはphp7ccをインストールする。手順はこちら。
コンテンツファイルのPHPソースを用意する
当たり前だけど、phpのソースファイル群を用意する。
php7cc実行
拡張子が、「.php」のファイル
$ php7cc 検査対象のフォルダ/ > php7result.txt
テキストファイルに記録しておく。
「php7result.txt」は任意の名前で構わない。
拡張子が「.php」以外のファイル
.php以外の拡張子のphpファイルを検査したいときには、
--extensions=拡張子
のオプションをつけてphp7ccを実行する。
例)
たとえば、.inc というファイルをphp7cc検査するには以下のようにコマンドを実行する。
php7cc --extensions=inc >> 検査対象フォルダ/
さっき拡張子が、「.php」のファイルをphp7ccした際、作ったファイルに「>>」で追記する。
php7対応(置換)用のシェルスクリプトを作成する
PHPコンテンツファイルが、php7で動くよう、コードを変えていく。
が、変更する量が多い場合は、一気に置換する手法を取るのが楽。
今回はシェルスクリプトを作って一気に置換する。
検査にひっかかったエラーの種類を特定する
まず、どんなエラーが検出されたのか、調べる。
php7ccの検査結果ファイルをコピーして編集していく。
Vimエディタでやる場合で記載する。
> Line
から始まる行だけに絞る。
:v/^> Line/d
↓
重複を省く。
:sort u
すると、なんのエラーが検出されたのかが分かる。
今回ワシの環境でやったときには以下の16個がひっかかった。
1 PHP 4 constructors are now deprecated
2 Possible array element creation during by-reference assignment
3 Possible internal array pointer access/modification in a by-value foreach loop
4 Possible object property creation during by-reference assignment
5 Removed function “ereg” called
6 Removed function “ereg_replace” called
7 Removed function “eregi” called
8 Removed function “mysql_data_seek” called
9 Removed function “mysql_fetch_array” called
10 Removed function “mysql_field_name” called
11 Removed function “mysql_field_table” called
12 Removed function “mysql_num_fields” called
13 Removed function “mysql_num_rows” called
14 Removed function “split” called
15 Removed regular expression modifier “e” used
16 Result of new is assigned by reference
このエラーリスト↑を取っておく。
エラー毎にphp7に対応した形に変更する。- コンストラクタの場合
エラーが16個出ているが、そのうち1個だけ編集するシェルスクリプトの書き方をメモする。
一個一個のエラー内容に応じて、やり方を変える必要があるが、似たようなやり方になると思う。
以下は、コンストラクタの修正を行う場合。
エラーの内容は、これ↓
1 PHP 4 constructors are now deprecated
コンストラクタに、クラス名と同じ名前の関数名を指定しているが
(class hoge の中に、
function hoge() みたいなやつ)、
php7ではそれは非推奨なので、
function __construct()
に変更する(関数の引数が在れば、そのまま引数つけたままで良い)。
やり方:
php7ccの検査結果ファイルをコピーして編集していく。
コピーしたファイルは.sh(シェルスクリプト)ファイルにする。
Vimでファイルを開く。
まずは、余計な行を削っていく。コンストラクタの行だけ残したいので、
以下のVimコマンドを一回ずつ実行する。
:%s/^.*Possible array element creation during by-reference assignment\n.*\n//
:%s/^.*Possible internal array pointer access\/modification in a by-value foreach loop\n.*\n//
:%s/^.*Possible object property creation during by-reference assignment\n.*\n//
:%s/^.*Removed function "ereg" called\n.*\n//
:%s/^.*Removed function "ereg_replace" called\n.*\n//
:%s/^.*Removed function "eregi" called\n.*\n//
:%s/^.*Removed function "split" called\n.*\n//
:%s/^.*Removed regular expression modifier "e" used\n.*\n//
:%s/^.*Result of new is assigned by reference\n.*\n//
:%s/^.*Removed function "mysql_data_seek" called\n.*\n//
:%s/^.*Removed function "mysql_fetch_array" called\n.*\n//
:%s/^.*Removed function "mysql_field_name" called\n.*\n//
:%s/^.*Removed function "mysql_field_table" called\n.*\n//
:%s/^.*Removed function "mysql_num_fields" called\n.*\n//
:%s/^.*Removed function "mysql_num_rows" called\n.*\n//
:g/^ [^f]/d
:g/^\n/d
:g/^Checked /d
:g/^ \n/d
下の4行以外は、コンストラクタ以外のエラー内容を削除するコマンド。
- コンストラクタじゃない他のエラーに対する修正シェルスクリプトを作成する場合、コンストラクタのエラー部分を削ることになるが、コンストラクタのエラー部分を削るコマンドは以下の通り
- :%s/^.*PHP 4 constructors are now deprecated\n.*\n//
下の4行の概要を以下にざっと書く。
:g/^ [^f]/d
は、行の頭からスペース4つがあり、「f」以外の文字から始まる行は削除するコマンド。
「f」から始まる文字列は、「function」だけのはず。
:g/^\n/d
は、何も書かれてない行を削除するコマンド
:g/^Checked /d
は、php7ccの検査結果のサマリーの行を削除するコマンド
:g/^ \n/d
は、半角スペース4つだけの行を削除するコマンド
↓
続いて、
以下を対象がなくなるまで何回も実行する。
:%s/^File:.*\n^\(File:\)/\1/
もういちど言う。
対象がなくなるまで何回も実行する。
↓
最下行が、
File:
から始まる行だったら、その最下行1行を削除する。
↓
> Line の行はもういらないので、消す。
Lineの行は、
- ●●●行目
- エラーメッセージ(今回の場合コンストラクタの警告)
が書いてある行なので、消す。
だが、この段階で、手動で修正できそうな量であった場合は、対象の
- ファイルPath
- 行番号
を見て、手動で修正してもよい。
> Line の行 を消すコマンドは以下。
:g/^> Line \d/d
↓
functionの行の頭のスペース4つを削る。
:%s/^ \(function.\{-\}(\).*/\1/
↓
function の行を置換するべく、sedコマンドの記述をする。
sedコマンドは念のためシェルスクリプトの変数($SED)で記述する。
:%s/^function/$SED -i -e 's\/function/
↓
:%s/\(^\$SED.*\)/\1\/' /
↓
冒頭の、「File: 」の部分を削る。
ついでに、検査したコンテンツファイルが在るPHPファイルのPATHで頭に余計なフォルダ名があった場合は、削る(あとでシェルスクリプトを実行する際、直接コンテンツのフォルダにシェルを配置して実行したい場合など)
:%s/^File: \/検査したコンテンツファイルが在るPHPのPATH\/検査したコンテンツファイルが在るPHPのPATH\///
↓
$SEDの行を作成する。
Vimのマクロ機能を使って編集。(ざっくりだな)
↓
SEDコマンドの行以外を削る
:v/^\$SED/d
↓
シェルスクリプトファイルの最上部に以下を追記する。
#!/bin/sh
SED=/usr/bin/sed
↓
保存
:wq
↓
パーミッション付与
$ chmod +x hoge.sh
↓
シェルスクリプト実行(実行場所に注意)
./hoge.sh
今回出たエラーの概要
Possible array element creation during by-reference assignment
参照代入によるもの。
エラー内容を日本語訳すると、
参照代入時に配列要素が生成される可能性があります。
& がついてるものだが、& を取り除くことで対応可能なのかな。
これは単純に&を消してあげるだけで動きます。
今回の自分のソースだと、smartyというPHPのテンプレートエンジンのソースのみがひっかかったので、smartyをPHP7に対応したものに差し替えることで対応した。
※ググったがあまり情報がなく、コードの検証も必要なかったのでしておりません。これを見られた方はご自身で検証などの調査を行った上でご対応ください
Possible internal array pointer access/modification in a by-value foreach loop
和訳:
値によるforeachループで内部配列ポインタにアクセス/変更される可能性
ググってもほとんど情報出て来ない。
以下によると、誤検知っぽい。
これは偽陽性だと思います。廃止されたphp7ccからの出力のようです。
Possible internal array pointer access/modification in a by-value foreach loop · Issue #454 · solariumphp/solariumFile: Solarium\QueryType\Analysis\ResponseParser\Field.php Line 114: Possible internal array pointer access/modification in a by-value foreach loop current($typ...
今回の自分のソースだと、smartyというPHPのテンプレートエンジンのソースのみがひっかかったので、smartyをPHP7に対応したものに差し替えることで対応した。
Result of new is assigned by reference
=& newを
= new
にすればいいやつ。
[Error] Result of new is assigned by reference
PHP 5 以降では、new 演算子が自動的に参照を返すように。
https://www.php.net/manual/ja/language.operators.assignment.php#language.operators.assignment.reference
$o = &new C;
↓
$o = new C;
PHP5から7へのバージョンアップ対応メモ主にIT系やプログラム系。実装や環境構築などでハマったところや情報が少ないことについて記事にしてます。
これは単純に&を消してあげるだけで動きます。
コメント