こんにちは。よっしーです(^^)
今日は、PHPのAttributes(属性)についてご紹介します。
背景
PHP8.2を利用したAPIを開発しているときにAttributes(属性)を利用したので、そのときの調査内容を備忘としてのこしました。
こちらのサイトを参考にしています。
Attributes(属性)へのアクセス
クラス、メソッド、関数、パラメータ、プロパティ、およびクラス定数から属性にアクセスするために、Reflection APIは対応するReflectionオブジェクトのそれぞれにgetAttributes()
メソッドを提供しています。このメソッドは、属性名、引数、および表現された属性のインスタンスを生成するためにクエリできるReflectionAttributeの配列を返します。
これにより、反映された属性の表現を実際のインスタンスから分離でき、プログラマーが属性クラスの不足、誤った型の引数、または欠落した引数に関するエラーを処理する制御を向上させます。ReflectionAttribute::newInstance() を呼び出した後、属性クラスのオブジェクトがインスタンス化され、引数の正しい一致が検証されます。それ以前にはインスタンス化されないため、エラーの検出と処理が柔軟に行えます。
この仕組みにより、属性の取得と処理に関する柔軟性が向上し、プログラムの正確性とエラーハンドリングが向上します。プログラマーは必要な属性情報を効果的に操作でき、属性に関連するエラーをより容易に特定および処理できます。
サンプル
<?php
#[Attribute]
class MyAttribute
{
public $value;
public function __construct($value)
{
$this->value = $value;
}
}
#[MyAttribute(value: 1234)]
class Thing
{
}
function dumpAttributeData($reflection) {
$attributes = $reflection->getAttributes();
foreach ($attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
var_dump($attribute->newInstance());
}
}
dumpAttributeData(new ReflectionClass(Thing::class));
/*
string(11) "MyAttribute"
array(1) {
["value"]=>
int(1234)
}
object(MyAttribute)#3 (1) {
["value"]=>
int(1234)
}
*/
このPHPコードは、属性(Attributes)を使用して、クラスにメタデータ情報を追加し、それをリフレクションを使用して取得する例です。以下はコードの解説です。
#[Attribute] class MyAttribute
:MyAttribute
という属性クラスを定義しています。この属性は値を受け取るコンストラクタを持ち、引数として渡された値を属性のプロパティ($value
)に設定します。#[MyAttribute(value: 1234)] class Thing
:Thing
というクラスにMyAttribute
を適用しています。この属性はvalue
引数に値1234
を指定しています。function dumpAttributeData($reflection)
: 属性情報を表示するための関数を定義しています。この関数は、Reflection APIを使用してリフレクションオブジェクトから属性情報を取得し、それを表示します。dumpAttributeData(new ReflectionClass(Thing::class))
:dumpAttributeData
関数を呼び出して、Thing
クラスに適用された属性情報を表示します。ReflectionClass
クラスを使用して、クラスThing
のリフレクションオブジェクトを作成しています。- 結果を表示:
dumpAttributeData
関数が呼び出されると、属性の情報が以下のように表示されます。
string(11) "MyAttribute"
: 属性の名前である “MyAttribute” が表示されます。array(1) { ["value"]=> int(1234) }
: 属性の引数情報が表示され、”value” という引数名に対して値1234
が指定されています。object(MyAttribute)#3 (1) { ["value"]=> int(1234) }
:newInstance()
メソッドを使用して、MyAttribute
の新しいインスタンスが作成され、その値が表示されます。
このコードは、属性を使用してクラスにメタデータ情報を関連付け、Reflection APIを介してそれを取得および表示する方法を示しています。属性はクラスやメソッドに関連する追加情報を提供し、それらの情報は実行時にプログラムにアクセスできます。
指定の属性へのアクセス
リフレクション・インスタンス上のすべての属性を反復する代わりに、検索された属性クラス名を引数として渡すことで、特定の属性クラスのものだけを取り出すことができます。
<?php
function dumpMyAttributeData($reflection) {
$attributes = $reflection->getAttributes(MyAttribute::class);
foreach ($attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
var_dump($attribute->newInstance());
}
}
dumpMyAttributeData(new ReflectionClass(Thing::class));
提供されたPHPコードは、指定された属性クラス(MyAttribute
)に関連する属性情報を取得し、それを表示するための関数を使用しています。以下はコードの解説です。
function dumpMyAttributeData($reflection)
: 属性情報を表示するための新しい関数dumpMyAttributeData
を定義しています。この関数はReflection APIを使用して、指定された属性クラス(MyAttribute
)に関連する属性情報を取得します。$attributes = $reflection->getAttributes(MyAttribute::class)
:$reflection
パラメータとして渡されたリフレクションオブジェクトから、指定された属性クラスMyAttribute
に関連する属性情報を取得します。この情報は$attributes
配列に格納されます。foreach ($attributes as $attribute) { ... }
: 取得した属性情報をループで処理し、各属性に対して次の処理を行います。var_dump($attribute->getName())
: 属性の名前を表示します。この場合、属性クラスMyAttribute
の名前が表示されます。var_dump($attribute->getArguments())
: 属性の引数情報を表示します。指定された属性の引数があれば、それらの情報が表示されます。var_dump($attribute->newInstance())
:newInstance()
メソッドを使用して、属性クラスMyAttribute
の新しいインスタンスを作成し、その値を表示します。dumpMyAttributeData(new ReflectionClass(Thing::class))
:dumpMyAttributeData
関数を呼び出して、Thing
クラスに適用された属性MyAttribute
の情報を表示します。ReflectionClass
クラスを使用して、Thing
クラスのリフレクションオブジェクトを作成しています。
このコードは、指定された属性クラスに関連する属性情報を取得し、それを表示する方法を示しています。属性はクラスやメソッドに関連する追加情報を提供し、Reflection APIを使用してそれらの情報にアクセスできます。
おわりに
今日は、PHPのAttributes(属性)についてご紹介しました。
何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。
それでは、また明日お会いしましょう(^^)
コメント