PHP入門:Attributes(属性)について -vol.3-

スポンサーリンク
PHP入門:Attributes(属性)について -vol.3- 用語解説
PHP入門:Attributes(属性)について -vol.3-
この記事は約8分で読めます。
よっしー
よっしー

こんにちは。よっしーです(^^)

今日は、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)を使用して、クラスにメタデータ情報を追加し、それをリフレクションを使用して取得する例です。以下はコードの解説です。

  1. #[Attribute] class MyAttribute: MyAttribute という属性クラスを定義しています。この属性は値を受け取るコンストラクタを持ち、引数として渡された値を属性のプロパティ($value)に設定します。
  2. #[MyAttribute(value: 1234)] class Thing: Thing というクラスに MyAttribute を適用しています。この属性は value 引数に値 1234 を指定しています。
  3. function dumpAttributeData($reflection): 属性情報を表示するための関数を定義しています。この関数は、Reflection APIを使用してリフレクションオブジェクトから属性情報を取得し、それを表示します。
  4. dumpAttributeData(new ReflectionClass(Thing::class)): dumpAttributeData 関数を呼び出して、Thing クラスに適用された属性情報を表示します。ReflectionClass クラスを使用して、クラス Thing のリフレクションオブジェクトを作成しています。
  5. 結果を表示: 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)に関連する属性情報を取得し、それを表示するための関数を使用しています。以下はコードの解説です。

  1. function dumpMyAttributeData($reflection): 属性情報を表示するための新しい関数 dumpMyAttributeData を定義しています。この関数はReflection APIを使用して、指定された属性クラス(MyAttribute)に関連する属性情報を取得します。
  2. $attributes = $reflection->getAttributes(MyAttribute::class): $reflection パラメータとして渡されたリフレクションオブジェクトから、指定された属性クラス MyAttribute に関連する属性情報を取得します。この情報は $attributes 配列に格納されます。
  3. foreach ($attributes as $attribute) { ... }: 取得した属性情報をループで処理し、各属性に対して次の処理を行います。
  4. var_dump($attribute->getName()): 属性の名前を表示します。この場合、属性クラス MyAttribute の名前が表示されます。
  5. var_dump($attribute->getArguments()): 属性の引数情報を表示します。指定された属性の引数があれば、それらの情報が表示されます。
  6. var_dump($attribute->newInstance()): newInstance() メソッドを使用して、属性クラス MyAttribute の新しいインスタンスを作成し、その値を表示します。
  7. dumpMyAttributeData(new ReflectionClass(Thing::class)): dumpMyAttributeData 関数を呼び出して、Thing クラスに適用された属性 MyAttribute の情報を表示します。ReflectionClass クラスを使用して、Thing クラスのリフレクションオブジェクトを作成しています。

このコードは、指定された属性クラスに関連する属性情報を取得し、それを表示する方法を示しています。属性はクラスやメソッドに関連する追加情報を提供し、Reflection APIを使用してそれらの情報にアクセスできます。

おわりに

今日は、PHPのAttributes(属性)についてご紹介しました。

よっしー
よっしー

何か質問や相談があれば、コメントをお願いします。また、エンジニア案件の相談にも随時対応していますので、お気軽にお問い合わせください。

それでは、また明日お会いしましょう(^^)

コメント

タイトルとURLをコピーしました