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 の新たなバグが報告されたり)来年以降の新規案件では使う機会があり、快適に開発できそうです。