PHP8.3がリリースされました。PHP8.3のEOLは2026-11-23です。PHP8.0のEOLは2023-11-26と差し迫っています。おすすめのリリース内容のまとめが次リンクです。
PHP: PHP 8.3.0 Release Announcement
【PHP8.3】PHP8.3の新機能 #PHP – Qiita
移行ガイドは次です。
PHP: PHP 8.2.x から PHP 8.3.x への移行 – Manual
私的に気になった点を紹介します
mb_str_pad
マルチバイト文字の文字列埋めがやりやすくなりました。以前は次のようにバイト長と文字列長が合わなかったため、str_padをそのまま日本語に使うと不具合の原因となりました。次のように使えます。
1 2 3 4 5 6 7 8 9 10 11 12 | <?php $char = 'あ' ; $padded = str_pad ( $char , 6, 'い' , STR_PAD_LEFT); var_dump( $padded ); // string(6) "いあ" $padded = mb_str_pad( $char , 6, 'い' , STR_PAD_LEFT); var_dump( $padded ); // string(18) "いいいいいあ" $padded = mb_str_pad( $char , 6, '👨🏻🦱' , STR_PAD_RIGHT); // string(22) "あ👨🏻🦱👨" |
ひらがなについていい感じに動いています。注意点として通常のマルチバイト文字対応のみで絵文字などの合字に使えない点があります。絵文字に使うと上記の顔文字の様に崩れます。絵文字に使う場合はgrapheme_strlenを元に自前でstr_pad相当を実装することになります。
PHP: grapheme_strlen – Manual
文字列からクラス定数を取得
次のようにクラス名::{任意の文字列}
というコードでクラス定数を得られるようになりました。
1 2 3 4 5 6 7 8 9 10 11 | <?php class Foo { const PHP = 'PHP 8.3' ; } $searchableConstant = 'PHP' ; var_dump(Foo::{ $searchableConstant }); // string(7) "PHP 8.3" |
特筆すべきはこれによりEnumが使いやすくなったことです。以前は次のように書いていましたが、
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 | enum State: string { case INIT = '初期' ; case COMPLETED = '完了' ; public static function find(string $key ): ?self { return match ( $key ) { 'INIT' => self::INIT, 'COMPLETED' => self::COMPLETED, default => null, }; } } $key = 'INIT' ; echo State::find( $key )->value; // 初期 // あるいは trait Findable { /** * foreach で線形探索するパターンです。 */ public static function findByForeach(string $key ): ? static { foreach ( static ::cases() as $enum ) { if ( $enum ->name === $key ) { return $enum ; } } return null; } } enum State: string { use Findable; case INIT = '初期' ; case COMPLETED = '完了' ; } $key = 'INIT' ; echo State::findByForeach( $key )->value; // 初期 |
PHP8.3からは次のように書けます。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | <?php enum State: string { case INIT = '初期' ; case COMPLETED = '完了' ; } // 存在するものを読むときは今までより大分楽になりました。 $key = 'INIT' ; var_dump(State::{ $key }->value); // string(6) "初期" // 存在しない場合に null を返すのはちょっと手間です。 // これは State::{$key} 時点で Fatal error: Uncaught Error: Undefined constant が発生するためです。 // ?? で存在しないなら null としたいのですが、そうしてもエラーが発生します。 // もし存在しない場合はnullを返すようにするのであれば、次のような関数を用意するのが良さそうです。 $key = 'NOT_EXIST' ; $getter = function (string $enum , $key ) { try { return $enum ::{ $key }->value; } catch (\Throwable $e ) { return null; } }; var_dump( $getter (State:: class , $key )); // NULL |
その場でPHPの機能だけで書けるようになるため扱いやすく、しかも高速です。
ランダム文字列生成
PHP: Random\Randomizer::getBytesFromString – Manual
ランダムな文字列を生成する機能がPHP組み込みの関数に追加されました。random_bytesをbase64して切り詰めたり伸ばしたりや外部ライブラリを使ったりする必要がなくなりました。あくまでバイト単位でのランダムなため日本語にたいしてそのまま使うべきではありません。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | <?php // $randomDomainについてのコードは ↑ から引用しました。 // A \Random\Engine may be passed for seeding, // the default is the secure engine. $randomizer = new \Random\Randomizer(); $randomDomain = sprintf( "%s.example.com" , $randomizer ->getBytesFromString( 'abcdefghijklmnopqrstuvwxyz0123456789' , 16, ), ); var_dump( $randomDomain ); //string(28) "hiqsw02bg93s8ycd.example.com" // rangeを使うと使う文字列の範囲がわかりやすく、漏れもおこしにくくなります。 $randomChars = implode( '' ,[...range(0, 9),...range( 'A' , 'Z' ), ...range( 'a' , 'z' )]); var_dump( $randomChars ); // string(62) "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" var_dump( $randomizer ->getBytesFromString( $randomChars , 16)); // string(16) "u1rhHuWZV87eOdhy" // Bytesの名前が示す通り、バイト単位でのランダムのため日本語をそのまま使うと文字化けします。 var_dump( $randomizer ->getBytesFromString( 'あいうえお' , 16)); // string(16) "���ぁ���め���" // 日本語を使う場合は配列の要素からランダムに選んでつなげる必要があります。 $randomChars = [ 'あ' , 'い' , 'う' , 'え' , 'お' ]; $randomCharsLastIdx = count ( $randomChars ) - 1; $result = '' ; for ( $i = 0; $i < 10; $i ++) { $result .= $randomChars [ $randomizer ->getInt(0, $randomCharsLastIdx )]; } var_dump( $result ); // string(30) "えいあああえうあうう" |
数値や数値形式の文字列以外に++や–を使うべきではない
PHP: PHP 8.3.x で推奨されなくなる機能 – Manual#加算子/減算子 に対する変更
数値らしいもの以外に++
や--
を使うと非推奨の警告が出る様になりました。アルファベットは++
は許されますが--
は非推奨です。実際に動かすと次のコードのようになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | <?php $a = '1' ; $a ++; var_dump( $a ); // int(2) $a --; var_dump( $a ); // int(1) $b = 'a' ; $b ++; var_dump( $b ); // string(1) "b" $b --; // Deprecated: Decrement on non-numeric string has no effect and is deprecated var_dump( $b ); // string(1) "b" $c = '' ; $c ++; // Deprecated: Increment on non-alphanumeric string is deprecated var_dump( $c ); // string(1) "1" $d = '' ; $d --; // Deprecated: Decrement on empty string is deprecated as non-numeric var_dump( $d ); // int(-1) $d = 'あ' ; $d ++; // Deprecated: Increment on non-alphanumeric string is deprecated var_dump( $d ); // string(3) "あ" $d --; // Deprecated: Decrement on non-numeric string has no effect and is deprecated var_dump( $d ); // string(3) "あ" |
数値以外の文字をずらすのであれば++
や--
をやめてstr_incrementやstr_decrementを使うべきというわけです。