【PHP】PHP8.1リリース

  • 2021年11月26日
  • 2024年2月21日
  • PHP

 PHP8.1 がリリースされました。PHP8.1 のセキュリティサポート期限は 2024/11/25 までです。PHP7.3 のセキュリティサポートは2021/12/06 に切れます。
 PHP 8.1 のリリースページは次です。リッチなぺージは英語版だけ(この英語版ページは日本時間 2021/11/26 午前3時頃にプッシュされました)ですが、更新点とマイグレーションガイドは日本語版もしっかりあります。major update とページの説明あるだけあって少なくない変更があります(8.0から8.1なのでメジャーバージョンのアップでなくマイナーバージョンのアップなのですが major update です)。
PHP: PHP 8.1.0 Release Announcement
PHP: News Archive – 2021#2021-11-25-1

PHP: PHP 8.0.x から PHP 8.1.x への移行 – Manual
 新機能は上記のアナウンスページや以下のページが読みやすいです。

【PHP8.1】PHP8.1の新機能 – Qiita
【PHP8.1】PHP8.1で削除される機能 – Qiita

 私的に特に便利な機能追加と変更は以下あたりです。
PHP: PHP 8.1.0 Release Announcement#new_in_initializers
 初期化中に new が使えます。公式例にあるようにデフォルト値で一旦 null を入れて、null か否かを検査して、といった手間な記述を減らせます。さすがに式はダメなので HogeClass::create の様な静的メソッドでインスタンスを生成するパターンをデフォルト値にしたい場合は旧来通りの null を用いましょう。

// @see https://www.php.net/releases/8.1/en.php#new_in_initializers
class Service
{
    private Logger $logger;
   
    public function __construct(
        Logger $logger = new NullLogger(),
    ) {
        $this->logger = $logger;
    }
}

// 公式例ではコンストラクタですが Initializers の名の通り関数でもメソッドでも new が使えます
<?php

class A
{
    public function callA($a = new A())
    {
        echo __METHOD__ ."\n";
    }
}

function argNew($a = new A())
{
    echo __METHOD__ . "\n";// argNew
    $a->callA();// A::callA
}

argNew();

PHP: PHP 8.1.0 Release Announcement#array_unpacking_support_for_string_keyed_arrays
 スプレッド演算子が連想配列相手でも使える様になりました。雑に使ってもバグになりにくくなります。

// @see https://www.php.net/releases/8.1/en.php#array_unpacking_support_for_string_keyed_arrays

$arrayA = ['a' => 1];
$arrayB = ['b' => 2];

$result = ['a' => 0, ...$arrayA, ...$arrayB];

// ['a' => 1, 'b' => 2]

// array_merge 要らずです。これまで連想配列が来る可能性がある場所では使えませんでしたが、今後は使えます

PHP: PHP 8.1.0 Release Announcement#readonly_properties
 簡単に読めるべきだが、簡単に操作できるべきでない、といったクラスを作る時によく用いていた getter メソッドが不要になりました。代わりに readonly キーワードを使えます。これにより複雑なロジックを押し込めたクラスでも比較的見通しがよくなります。

class BlogData
{
    public readonly Status $status;
  
    public function __construct(Status $status)
    {
        $this->status = $status;
    }
}

 また PHP のコードをより厳密にするための機能もいくらか増えています。以前自分がバグを起こした原因を防いでくれたであろう項目に次があります。
PHP: PHP 8.1.x で推奨されなくなる機能 – Manual#暗黙の float から int への変換
 公式の例では配列のキーについて書かれています。この変換は実は関数の引数にも適用されます。これは次の様に働きます。

<?php

function withConvertToInt(int $a)
{
    var_dump($a);
}
// 警告なし
// var_dump では int(1) が出力
withConvertToInt(1);

// Deprecated: Implicit conversion from float 15.1 to int loses precision in xxx\test.php on line 3
// var_dump では int(15) が出力
withConvertToInt(15.1);

// 警告なし
// var_dump では int(14) が出力
withConvertToInt('14');

// Deprecated: Implicit conversion from float-string "14.3" to int loses precision in xxx\test.php on line 3
// var_dump では int(14) が出力
withConvertToInt('14.3');

 以前、元々 float で値を受け取る関数を int 型を引数に取る関数でラッピングして小数以下の細かい調整ができなくなったことがありましたが、これがあればすぐに問題に気づけました(元々declare(strict_types=1)を用いていれば PHP8.1 でなくとも気づけたことではありますが)。
 加えて、いい感じの具体例は挙げられませんが返り値の never 型、グルーピングすべき定数をいい感じにまとめられる Enum あたりが使いどころ多そうです。
 さすがにすぐ業務に導入とはいきませんが(2021/11/26 16:00頃に DateTimeZone::getTransitions の新たなバグが報告されたり)来年以降の新規案件では使う機会があり、快適に開発できそうです。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG