その他の変更
最後に、上記以外の変更をまとめておきます。
動的プロパティ禁止(Deprecate dynamic properties)[8.2]
動的プロパティとは、クラスに存在しないプロパティを動的に生成できるという機能です。たとえば以下のリストのように、空のクラスのインスタンスに動的にプロパティxを追加できました。
PHP 8.2では、この動的プロパティが禁止されます。ただし、E_DEPRECATEとなって警告メッセージが出力されますが、プロパティの追加は実行されています。将来のバージョン(9.0)では完全に使用できなくなることになっていて、動的プロパティの生成で例外が発生するようになります。
class EmptyClass { // 定義は何もない } $e = new EmptyClass(); $e->prop = 1; // Creation of dynamic propertyの警告が出る var_dump($e); // $eの内容が表示される
なお、PHP 8.2より利用可能になったアトリビュート[\AllowDynamicProperties]をクラスに付与することで、この制約を除去して従来どおりに動的プロパティが許可されるようになります。
#[\AllowDynamicProperties] class EmptyClass { …略…
トレイト内の定数(Constants in Traits)[8.2]
トレイトとは、コードの再利用を目的とする機能です。トレイトはクラスなどと同様にtraitキーワードによって定義し、内部にはメソッドやプロパティを含めることができます。あるクラスとトレイトを継承したクラスで同じメンバーがある場合、優先順位は当該クラス、トレイト、基底クラスの順となります。
このトレイトには、これまで定数を記述することができませんでした。これは、あえて外していたということではなく、単に漏れていたということのようですが、PHP 8.2でようやくトレイトに定数を記述できるようになりました。
ただし、トレイト内の定数は、重複が認められません。他に継承されるトレイトはもちろんのこと、継承する側のクラスでも定義できません。as演算子によるエイリアスも、insteadofによる衝突回避も禁止されています。
以下のリストはトレイト内の定数の例です。双方とも同じ定数を持っているので、MyClassの宣言時にエラーとなります。
trait MyTrait1 { public const CONSTANT = "Constant1"; } trait MyTrait2 { public const CONSTANT = "Constant2"; } class MyClass { use MyTrait1, MyTrait2; // MyTrait1 and MyTrait2 define the same constantのエラーとなる }
文字列内変数展開を一部廃止[8.2]
文字列内変数の展開書式の一部が廃止されました。展開書式には、以下のリストに挙げる書式がありました。
$foo = "Hello"; $bar = 'foo'; echo "$foo"; // ①$変数名 echo "{$foo}"; // ②$変数名を{}で囲む echo "${foo}"; // ③$に{変数名} ⇒廃止 echo "${$bar}"; // ④変数名の間接参照 ⇒廃止
このうち、上記で「⇒廃止」とコメントされている書式③④は、PHP 8.2ではE_DEPRECATEDとなり警告メッセージが出力され、将来のバージョン(9.0)で削除されます。②では「{$foo->func()}」のような記述が可能ですが、③では「${foo->func()}」とは記述できずに紛らわしいとされました。④も同様の理由です。
引数をセンシティブパラメータとするアトリビュート#[\SensitiveParameter][8.2]
スタックトレースに出力する引数の値をマスクできるようにします。ユーザのパスワードやデータベースの接続文字列などは、センシティブパラメータと呼ばれて秘匿性が重要視されるものですが、これらが関数の引数であるときにセンシティブパラメータと指定できるようになります。センシティブパラメータに指定された引数は、スタックトレースでは「Object(SensitiveParameterValue)」と出力されるようになります。以下のリストは、パスワードを表す引数passをセンシティブパラメータに指定します。
function login( $user, #[\SensitiveParameter] $pass ) { throw new Exception('ログインできません!'); } login('nao', 'Password');
実行結果は下記です。
Fatal error: Uncaught Exception: ログインできません! in …/sensitive_param.php:7 Stack trace: #0 …sensitive_param.php(10): login('nao', Object(SensitiveParameterValue))
まとめ
今回は、PHP 8.2の新機能のうち、callable構文や関数サポートに関連する変更を中心に紹介しました。
PHPでは、このように非常に細かな改変が各バージョンで施されています。よりモダンで使い勝手のよい言語として成長し続けるPHPを、今後も見守っていきたいものです。