【PHP】PHP7から8への移行のために知るべきこと

PHP

1. 概要

前回はPHP8の新機能を紹介しましたが、変更点もいくつもありますので、そちらを具体的なコードと共に学んでいきましょう。

下位互換性のない変更もあり、そのままバージョンを上げてしまうとバグやエラーとなってしまいかねないので、慎重で確実な対応が必要です。

今回は、個人的に大きい変更だと思うものをいくつかピックアップします。

2. 文字列と数値の比較

黙認状態だった厳密でない比較「==」に、変更があったようです。

(厳密でないやり方で)数値と非数値文字列を比較する場合、 数値を文字列にキャストし、文字列と比較するようになりました。 数値と数値形式の文字列の比較は、以前と同じ振る舞いをします。 注意すべきなのは、これによって、 0 == "not-a-number" が false と見なされるようになったことです。

比較変更前変更後
0 == ‘0’truetrue
0 == ‘0.0’truetrue
0 == ‘foo’truefalse
0 == ”truefalse
42 == ‘ 42’(半角スペースあり)truetrue
42 == ’42foo’truefalse
文字列と数値の比較

これは、比較する仕様が変わったことによるものです。

PHP 7までは、数値文字列ではない文字列を無理やり数値にキャストしてから数値同士を比較していたため、下記の判定式はすべて true でした。しかし、PHP 8からは、数値の方を文字列にキャストしてから文字列同士を比較するようになったため、より直感的な判定結果を得られるようになりました。

PHP8技術者認定初級試験公式問題集A

これまでは数値に変換して比較していたものが、今後は文字列に変換して比較するようになりました。

型は厳しく比較しておかないとバグの温床になるので、なるべくならもともと「===」で比較をするのが一番ですね!

ここで見落としがちなのが、内部的に「==」で比較するものにも注意が必要です。

PHP8新機能紹介の「6. match式のサポート」でも紹介しましたが、switchです。

switchは「==」の比較なので、見落としがちなポイントです。バージョンアップの際は注意しましょう。というか、この機にmatchやif /elseif / elseで「===」にしてしまってもいいのでは??

$num = 0; // int型
switch ($num) {
    case 'foo': // 0 == 'foo'
        echo "0 == 'foo'が成立";
        break;
    default:
        echo "該当なし";
        break;
}

// PHP7.4 → 0 == 'foo'が成立
// PHP8.2 → 該当なし

3. 予約語の追加

match、mixedが予約語になりました。VSCodeを愛用している方は脳死でCtrl + Shift + F(一括検索)しましょう!

matchは関数なので当たり前ですね。正規表現や文字列検索を行う箇所のメソッド名として使ってませんか??

mixedはクラスやインターフェイス、 トレイトの名前として使えなくなったそうです。名前空間の中であってもです。むしろ今まで使えてたんですね。

4. クラス名と同じメソッド名はコンストラクタとして認識されなくなる

しっかり__constructを使いましょうって話です。というか同じメソッド名だと勝手に実行されることを知りませんでした。

class Narcissist
{
    /**
     * クラスメイト同じメソッド名
     */
    public function narcissist()
    {
        echo '俺、カッコイイ!';
    }
}

$narcissist = new Narcissist();

// PHP7.4 → ナルシスト
// PHP8.2 → 初手は何も言わないが、narcissistメソッドを呼べば本性を現す

5. 三項演算子のネスト時に明示的なカッコが必要になった

if / else だけならスマートに書ける三項演算子ですが、ネストが必要になった場合はカッコで明示的に区切らなければならなくなりました。

そもそもネストが必要になるなら if / else にした方がいいと個人的に思いますが、、、例を紹介します。

// if / elseで書く場合
if ($isAcquireRasengan) {
    if ($isSonOf4thHokage) {
        $human = 'うずまきナルト';
    } else {
        $human = '自来也、はたけカカシとか';
    }
} else {
    if ($isAcquireChidori) {
        $human = 'うちはサスケ';
    } else {
        $human = '他いろいろ';
    }
}

↓

// ~PHP7.4 三項演算子
$human = $isAcquireRasengan
    ? $isSonOf4thHokage ? 'うずまきナルト' : '自来也、はたけカカシとか'
    : $isAcquireChidori ? 'うちはサスケ' : '他いろいろ';

// PHP8.0~ 三項演算子
$human = $isAcquireRasengan
    ? ($isSonOf4thHokage ? 'うずまきナルト' : '自来也、はたけカカシとか')
    : ($isAcquireChidori ? 'うちはサスケ' : '他いろいろ');

確かにカッコで囲うことによりどこで区切られるかもわかりやすくなりました。

ただやっぱり、 if /else の方が個人的には・・

6. マルチバイト文字列の関数がいろいろ変わった

エイリアスがいくつも削除され、関数の挙動も微妙に変わっているようです。

詳しくはこちら。ここでは紹介しませんが、全て一括検索しておきましょう。

7. 最後に

今回は、PHP7から8の破壊的な変更をいくつかピックアップしました。

他にも細かい変更点はたくさんあるので、7系以下のシステムをバージョンアップさせる際は要チェックです。

8. 参考

PHP: 下位互換性のない変更点 – Manual

投稿者プロフィール

KatoShingo
学んだことをアウトプットしていきます!
好きなこと:音楽鑑賞🎵 / ドライブ🚗 / サウナ🧖

関連記事

  1. PHP

    【PHP】PHP8の新機能を具体的なコードで理解する

最近の記事

  1. Node.js
  2. AWS
  3. AWS

制作実績一覧

  1. Checkeys