
背景
あるプロダクトをPHP5.6からPHP7にアップデートする対応をしたので、その時に修正した点まとめです。あくまでもその時に修正した点をまとめたもので、PHP7での変更点を全てまとめたわけではありません。
また、mysql系関数が廃止される件については、長くなりそうなので機会があれば別でまとめたいと思います。
php7ccを利用したチェック
まずは変更しなければいけない箇所を洗い出すために php7cc を利用します。
php7ccのインストール
composer を使ってphp7ccをインストールします。composerのインストール方法などについては割愛します。
php7ccをグローバルにインストールします。以下のコマンドです。
$ composer global require sstalle/php7cc
これで ~/.composer/vandor/ 以下にphp7ccがインストールされましたので、PATHを通します。僕はzshを使っているので、 ~/.zshrc に以下を追記しました。
export PATH=$PATH:~/.composer/vendor/bin
これでphp7ccコマンドが使えるようになると思います。設定ファイルを読み直します。
$ source ~/.zshrc
php7cc の使い方
以下のコマンドを叩くと、PHP7で使えなくなった箇所をリストアップしてくれます。
$ php7cc <ファイルorディレクトリ>
ファイルを指定するとそのファイルに含まれているPHP7非対応の文法を、ディレクトリを指定するとそのディレクトリの下にあるファイル全てを調べてPHP7非対応の文法をリストアップしてくれます。
> Line 1723: PHP 4 constructors are now deprecated
function MarkdownExtra_Parser()
{
}
> Line 2353: Removed regular expression modifier "e" used
preg_replace('#(.)#es', '"' . $boundary . '" . str_pad(dechex(ord(substr("\\1", -1))), 2, "0", STR_PAD_LEFT)', $fragment);
赤くなっているのがPHP7非対応の部分です。この部分を修正していく必要があります。
PHP7化にあたり修正が必要だった箇所
- 古い形式のコンストラクタ
- 参照渡しnewの削除
preg_replace関数のe修飾子が使えなくなったString,Intという名前のクラスは定義できなくなった
古い形式のコンストラクタ
PHP4までは以下の形式のコンストラクタを使っていました。
class Human {
private $age;
public function Human($age) {
$this->age = $age
}
}
$humane = new Human(25);
しかし、PHP5以降、コンストラクタメソッドは __construct に変更されました。
class Human {
private $age;
public function __construct($age) {
$this->age = $age
}
}
PHP 5.6までは互換性のため、PHP4スタイルのコンストラクタが使えていましたが、PHP 7からは古いコンストラクタは使えなくなるため、すべて __construct に置き換える必要があります。
参照渡しnewの削除
参照渡しnewはPHP7から使えなくなりました。以下の様な書き方です。
$human =& new Human(25);
これは単純に&を消してあげるだけで動きます。
$human = new Human(25);
参照だとかポインタだとか面倒なことを考えなくてよくなりました。
preg_replace 関数の e 修飾子が使えなくなった
preg_replace には e 修飾子というものがありました。
<?php
$result = preg_replace('/[a-e]+/e', 'strtoupper("$0")', 'abcdefgHIJ102');
echo $result . "\n";
これの結果は ABCDEfgHIJ102 となります。e修飾子を使うと、第2引数がPHPプログラムとして解釈されます。
- 正規表現
[a-e]+にabcdeがマッチ abcdeの部分がstrtoupper("abcde")の結果に置き換えられる- つまり、
abcdeがABCDEに置き換えられる ABCDEfgHIJ102となる
しかしこれは見るからに脆弱性を生みそうなコードです。PHP 5からこの文法は非推奨になる、7で削除されることになりました。PHP 7にバージョンアップするに当たり、preg_replace_callback を利用して書き換える必要があります。
<?php
$result = preg_replace_callback(
'/[a-e]+/',
function ($matches) {
return strtoupper($matches[0]);
},
'abcdefgHIJ102'
);
echo $result . "\n";
これで安全にもなります。
参考
- http://php.net/manual/ja/function.preg-replace.php
- http://php.net/manual/ja/reference.pcre.pattern.modifiers.php
- http://php.net/manual/ja/function.preg-replace-callback.php
String, Int という名前のクラスは定義できなくなった
今までは class String や class Int というクラスが定義可能でしたが、PHP7からは定義できなくなりました。クラスとして定義できなくなった名前は以下の通りです。(大文字小文字区別なく定義できなくなりました)
- bool
- int
- float
- string
- null
- true
- false
また、以下の文字列も将来的に定義できなくなる可能性があるので定義しないほうが無難です。
- resource
- object
- mixed
- numeric
今回StringやIntといったクラスが定義できなくなったのは、おそらく、stringやintのタイプヒントが可能になった関係だと思います。StringやIntのような名前のクラスを定義している場合はクラス名を変えてやる必要があります。
まとめ
今回は、php7ccのインストール方法と、PHP 7になって使えなくなる機能について一部をまとめました。
PHP 7では、intやstringといったプリミティブ型のタイプヒントを始めとして有用な機能が多数追加されています。また、PHP 5.6も2018年末でサポートが切れますので、以下に上げるマニュアルを参考にしてPHP 7へのバージョンアップの準備を進めていきましょう。
参考
- 作者:山田 祥寛
- 発売日: 2016/04/09
- メディア: 単行本(ソフトカバー)