はじめに
PHPにはユーザ側で使用できる定義済みのアトリビュートがいくつか用意されています。
本記事ではPHPで利用できる定義済みアトリビュートについて、使い方をコード例を添えて紹介します。
一覧
| アトリビュート | PHP Version | 概要 |
|---|---|---|
| Attribute | 8.0 | アトリビュートを定義する |
| ReturnTypeWillChange | 8.1 | 互換性のない戻り値の警告を抑制する |
| AllowDynamicProperties | 8.2 | 動的プロパティを使う |
| SensitiveParameter | 8.2 | 機密値を隠す |
| Override | 8.3 | メンバーをオーバーライドする |
| Deprecated | 8.4 | 機能が非推奨であることを示す |
| DelayedTargetValidation | 8.5 | 内部アトリビュートのエラーを抑制する |
| NoDiscard | 8.5 | 関数の戻り値を変数に入れるように強制する |
Attribute
(PHP8.0)
アトリビュートを定義するためのアトリビュートです。
引数には
・対象にできる機能を指定する(TARGET_〇〇)
・同じ対象へ繰り返し指定可能にする(IS_REPEATABLE)
のフラグが指定できます。(省略した場合はTARGET_ALL)
また、これらのアトリビュートにはリフレクションAPIを使ってアクセスする事ができます。
#[\Attribute(\Attribute::TARGET_FUNCTION|\Attribute::TARGET_METHOD)]
class CustomFunctionAttribute {}
#[CustomFunctionAttribute]
function foo(): void {}
$attributes = new \ReflectionFunction(foo(...))->getAttributes();
foreach ($attributes as $attr) {
echo $attr->getName(); // "CustomFunctionAttribute"
}
ReturnTypeWillChange
(PHP8.1)
内部クラスのメソッドをオーバーライドしたときの互換性のない戻り値の型の非推奨警告を抑制するためのアトリビュートです。
主にPHPバージョン間の互換性を保つためにオーバーライドしているメソッドの戻り値を宣言できない場合などに使用します。
※ユーザ定義メソッドの戻り値の型はオーバーライドしている側と互換性がない場合、致命的なエラーとなるためこのアトリビュートは使えません。
// \CountableはPHP側で定義されているインターフェイス
class CountWithoutAttribute implements \Countable
{
public function count() {
return 1;
}
}
// \Countable::count()の戻り値はintと定義されているため、以下の警告が発生する
// output:
// Deprecated: Return type of CountWithoutAttribute::count() should either be compatible with Countable::count(): int, or the #[\ReturnTypeWillChange] attribute should be used to temporarily suppress the notice in php-wasm run script on line 3
class CountWithAttribute implements \Countable
{
#[\ReturnTypeWillChange]
public function count() {
return 1;
}
}
AllowDynamicProperties
(PHP8.2)
動的なプロパティを使うときに指定するアトリビュートです。
PHP8.2以降、動的なプロパティは推奨されなくなったので、このアトリビュートを指定せずに動的なプロパティを使うと非推奨の警告が発生します。
class NormalClass {}
$class = new NormalClass();
$class->foo = 'test';
// output:
// Deprecated: Creation of dynamic property NormalClass::$foo is deprecated in php-wasm run script on line 4
#[\AllowDynamicProperties]
class HasDynamicProperties {}
$class = new HasDynamicProperties();
$class->foo = 'test';
SensitiveParameter
(PHP8.2)
認証情報など機密性の高い情報をスタックトレースに表示されないようにするアトリビュートです。
class DB
{
public static function connect(
string $user,
string $password,
) {
// ...
throw new \Exception ('Connection failed.');
}
public static function secureConnect(
string $user,
#[\SensitiveParameter]
string $password,
) {
// ...
throw new \Exception ('Connection failed.');
}
}
DB::connect('user', 'secretValue');
// スタックトレースに引数がそのまま表示されている
// output:
// Fatal error: Uncaught Exception: Connection failed. in php-wasm run script:8 Stack trace:
// #0 php-wasm run script(21): DB::connect('user', 'secretValue')
// #1 {main} thrown in php-wasm run script on line 8
DB::secureConnect('user', 'secretValue');
// スタックトレースで機密値が Object(SensitiveParameterValue) と表示されている
// output:
// Fatal error: Uncaught Exception: Connection failed. in php-wasm run script:17 Stack trace:
// #0 php-wasm run script(23): DB::safeConnect('user', Object(SensitiveParameterValue))
// #1 {main} thrown in php-wasm run script on line 18
Override
(PHP8.3)
メソッドやプロパティをオーバーライドするときに指定するアトリビュートです。
#[Override]を指定したメソッドやプロパティが親クラスに存在しない場合、コンパイルエラーが発生します。
インターフェイスで定義されたメソッドやプロパティを実装していることを示すのにも使用できます。
※プロパティに対しての指定はPHP8.5で追加されました。
class ParentClass
{
public function parentMethod(): void {}
}
class ChildClass extends ParentClass
{
#[\Override]
public function parentMethod(): void {}
#[\Override]
public function childMethod(): void {}
}
// output:
// Fatal error: ChildClass::childMethod() has #[\Override] attribute, but no matching parent method exists in php-wasm run script on line 12
Deprecated
(PHP8.4)
定数や関数、クラスを非推奨にするときに指定するアトリビュートです。
リフレクションAPIのisDeprecated()で指定した関数などが非推奨であるか確認できます。
#[\Deprecated]
function oldFunction(): void {}
oldFunction();
// output:
// Deprecated: Function oldFunction() is deprecated in php-wasm run script on line 4
function newFunction(): void {}
$oldFunction = new \ReflectionFunction(oldFunction(...));
$oldFunction->isDeprecated(); // true
$newFunction = new \ReflectionFunction(newFunction(...));
$newFunction->isDeprecated(); // false
DelayedTargetValidation
(PHP8.5)
PHPで定義されている内部アトリビュートのコンパイルエラーをアトリビュートがインスタンス化されるまで遅延するようにするアトリビュートです。
PHP8.5で追加されたため機能するのはPHP8.5より後のバージョンになってきます。
今後PHPのいずれかの内部アトリビュートの対象が拡張されたとき(例えば#[\Override]がプロパティにも指定できるようになったように)古いバージョンでエラーを抑制してコードの互換性を保つことが可能です。
class ParentClass
{
public function parentMethod(): void {}
}
class ChildClass extends ParentClass
{
#[\DelayedTargetValidation]
#[\Override]
public const CHILD_CONST = 'foo';
#[\Override]
public function parentMethod(): void {}
}
// PHP8.5以前からDelayedTargetValidationがあれば
// PHP8.5より前のバージョンで実行しても以下のコンパイルエラーは出なくなる
// output:
// Fatal error: Attribute "Override" cannot target class constant (allowed targets: method) in php-wasm run script on line 10
NoDiscard
(PHP8.5)
関数の戻り値を無視してほしくないときに指定するアトリビュートです。
#[\NoDiscard]
function getValue(): string
{
return 'important';
}
getValue();
// output:
// Warning: The return value of function getValue() should either be used or intentionally ignored by casting it as (void) in php-wasm run script on line 7
// 意図的に戻り値を無視する場合はこのように書くことができます。
(void) getValue(); // PHP8.5 以降
$_ = getValue(); // PHP8.5 より前