📘

PHP5からPHP8へのマイグレ

2024/09/10に公開

PHP 5からPHP 8への移行でのポイントを馴染みのJavaを介して説明します。

以下、chatGPTのサポートにより作成しています。

1. 型宣言のサポート

PHP 8では、Javaと同様に厳格な型宣言が強化されています。関数やメソッドの引数、戻り値に型を指定できるようになりました。PHP 5では型を気にせずに書けましたが、PHP 8では厳密な型を使うことで、コードがより明確で安全になります。

例:

// PHP 5
function add($a, $b) {
    return $a + $b;
}

// PHP 8
function add(int $a, int $b): int {
    return $a + $b;
}

Javaにおける型宣言に似た概念で、PHP 8では型が必須ではありませんが、推奨されています。

2. match式の導入

PHP 8ではswitch文に代わるmatch式が導入されました。これはJavaのswitch文に似ていますが、より短く、強力です。

例:

// PHP 5のswitch文
switch ($status) {
    case 1:
        $result = 'One';
        break;
    case 2:
        $result = 'Two';
        break;
    default:
        $result = 'Other';
}

// PHP 8のmatch式
$result = match($status) {
    1 => 'One',
    2 => 'Two',
    default => 'Other',
};

Javaのswitch文に近い構文ですが、matchの方が式として使えるため、より柔軟です。

3. 名前付き引数

Javaのキーワード引数のように、PHP 8では名前付き引数が導入され、引数を順番に依存せずに渡すことが可能です。

例:

// PHP 8
function greet($name, $greeting) {
    return "$greeting, $name!";
}

echo greet(greeting: "Hello", name: "Alice");

引数の順番を気にせず、明確にコードが書けます。

4. コンストラクタのプロモーション

PHP 8では、Javaと同様にクラスのプロパティを簡単に初期化するためにコンストラクタプロモーションが導入されました。

例:

// PHP 5
class User {
    public $name;
    public $email;

    public function __construct($name, $email) {
        $this->name = $name;
        $this->email = $email;
    }
}

// PHP 8
class User {
    public function __construct(public string $name, public string $email) {}
}

Javaのコンストラクタのように、PHP 8ではプロパティを直接コンストラクタの引数で初期化できます。

5. Null安全演算子

PHP 8では、JavaにあるようなOptionalのように、nullチェックを簡素化するnull安全演算子が使えるようになりました。

例:

// PHP 5でのnullチェック
if ($user !== null) {
    $name = $user->name;
} else {
    $name = null;
}

// PHP 8でのnull安全演算子
$name = $user?->name;

6. 非推奨の機能の削除

PHP 5で使用されていた多くの機能がPHP 8で削除されています。例えば、create_function()ereg()などの古い正規表現関数が削除されています。これらは、preg_*関数や無名関数に置き換える必要があります。


PHP 8ではパフォーマンスの向上とともに、エラーハンドリングや新機能の追加がされています。これらの点を考慮すると、移行がスムーズになります。

7. 強化されたエラーハンドリング

PHP 7以降、Fatal ErrorExceptionとして扱われるようになり、PHP 8ではさらにエラーハンドリングが強化されています。TypeErrorErrorクラスの例外がより詳細に処理されるため、例外処理の再設計が必要な場合があります。

例:

// PHP 5ではFatal Error
function test($a) {
    return $a + 1;
}
echo test("string"); // TypeError in PHP 8

PHP 8では、タイプミスマッチの場合にTypeErrorが投げられるため、これらのエラーをキャッチして適切に処理する必要があります。

8. コンパイル時の警告の強化

PHP 8では、以前のバージョンよりも厳格な警告が発生することがあります。特に、未定義の変数や未定義の配列インデックスにアクセスした場合などに警告が出る可能性があります。これらを適切に修正する必要があります。

例:

// PHP 5ではNoticeのみ
echo $undefinedVariable;

// PHP 8ではWarning

未定義の変数やプロパティにアクセスするコードは、事前に存在チェックを行うように修正するのが良いです。

9. 算術演算に関する変更

PHP 8では算術演算での挙動も変更されました。特にNaNINFに関しては、Javaに近い挙動になっており、これらが含まれる演算には注意が必要です。

例:

// PHP 8でのINFの扱い
$result = 5 / 0; // INF

PHP 5ではこれがWarningを出すだけでしたが、PHP 8ではINFが返され、より明確にエラー処理が可能です。

10. 非推奨関数と機能の削除

PHP 5で使用されていた多くの関数が非推奨または削除されているため、それらを新しい関数に置き換える必要があります。例えば、each()関数は削除されており、foreachループを使用する必要があります。

例:

// PHP 5で使用されていたeach()
while (list($key, $value) = each($array)) {
    echo "$key => $value";
}

// PHP 8ではforeachを使用
foreach ($array as $key => $value) {
    echo "$key => $value";
}

11. 正規表現の改善

PHP 8では、正規表現エンジンがPCRE2にアップグレードされました。これに伴い、古い正規表現のパターンが動作しない場合がありますので、正規表現のコードも確認する必要があります。

12. ジェネリックなコレクション型

PHP 8には、まだJavaのような完全なジェネリック型は存在しませんが、ユーザー定義型に基づく厳密な型チェックができるようになっています。iterable型やobject型の利用が推奨されています。

例:

function processItems(iterable $items) {
    foreach ($items as $item) {
        // 処理
    }
}

13. 属性(アノテーション)のサポート

Javaでのアノテーションのように、PHP 8では#[Attribute]という形で属性(アノテーション)がサポートされるようになりました。これは、メタデータを簡単に扱えるようにするもので、フレームワークなどで広く活用されることが予想されます。

例:

#[Route('/path')]
class MyController {
    // コントローラーロジック
}

14. JITコンパイルの導入

PHP 8ではJIT(Just-In-Time)コンパイルが導入され、パフォーマンスが向上しました。Javaと同じく、コンパイル時間と実行時間のバランスを考慮してパフォーマンス最適化が行われますが、すべてのスクリプトで有効とは限らないため、JITの恩恵を受けるかどうかは検討が必要です。

15. 静的分析ツールの活用

PHP 8では、静的分析ツール(例えばPHPStanPsalm)を使うことで、コードの型や潜在的なエラーを事前に検出することが推奨されています。JavaでもFindBugsCheckstyleのようなツールが使われますが、PHP 8のプロジェクトでもこれらを利用することで、移行時のバグを未然に防ぐことができます。


EOF

Discussion