WebエンジニアのLoL日記

LoLをプレイしたりLJLの試合を見たりするのが好きなエンジニア。LoLのイベントやパッチノートなど気になった点を記事にしたり、LJLについの記事をかいたりしています。某社でWeb系のエンジニアとして働いているので、技術系の記事もたまに書きます。コンタクトを取りたい場合はtwitterまで。

PHP5.6からPHP7系にするときに修正した点まとめ

背景

あるプロダクトをPHP5.6からPHP7にアップデートする対応をしたので、その時に修正した点まとめです。あくまでもその時に修正した点をまとめたもので、PHP7での変更点を全てまとめたわけではありません。

また、mysql系関数が廃止される件については、長くなりそうなので機会があれば別でまとめたいと思います。

f:id:yoshiki_utakata:20180101215400j:plain

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プログラムとして解釈されます。

  1. 正規表現 [a-e]+abcde がマッチ
  2. abcde の部分が strtoupper("abcde") の結果に置き換えられる
  3. つまり、abcdeABCDE に置き換えられる
  4. 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";

これで安全にもなります。

参考

String, Int という名前のクラスは定義できなくなった

今までは class Stringclass 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へのバージョンアップの準備を進めていきましょう。

参考