【PHP8.x】TARGET_CLASS定数の使い方

TARGET_CLASS定数の使い方について、初心者にもわかりやすく解説します。

作成日: 更新日:

基本的な使い方

Attribute::TARGET_CLASS定数は、PHP 8で導入された「属性(Attributes)」が適用される対象の一つとして、クラスを表す定数です。

PHPの属性は、コード自体に追加情報を付与するメタデータのような機能であり、従来のdocコメントよりも明確かつ構造化された方法で、フレームワークなどが特定のクラスやメソッドを認識し、特別な処理を行うための目印として利用されます。

属性は、クラス、メソッド、プロパティ、関数、定数、パラメータなど、様々なPHPの要素に適用することができます。しかし、特定の属性を定義する際、その属性が「どのPHP要素にのみ適用できるか」を制限したい場合があります。例えば、特定の属性はクラス定義の上部にのみ記述を許可し、メソッドには記述を許可しない、といった制約です。

Attribute::TARGET_CLASS定数は、まさにこの制限を指定するために使われる定数の一つです。新しい属性を定義する際、その属性クラスの定義元に#[Attribute(Attribute::TARGET_CLASS)]のように指定することで、「この属性はPHPコード内のクラス定義に対してのみ記述できます」という制約を明示的に設定できます。

これにより、開発者が誤った場所に属性を適用することを防ぎ、コードの意図を明確にするとともに、属性を解析するツールやフレームワークが、どこにその属性が期待されているかを正確に判断できるようになります。Attribute::TARGET_CLASSは、属性の柔軟な利用をサポートしつつ、コードの堅牢性と保守性を向上させるための重要な要素です。

構文(syntax)

1<?php
2
3#[Attribute(Attribute::TARGET_CLASS)]
4class ForClassOnlyAttribute
5{
6}
7
8#[ForClassOnlyAttribute]
9class MyClass
10{
11}

引数(parameters)

戻り値(return)

int

Attribute::TARGET_CLASS は、この属性がクラスに適用されることを示す定数で、整数値 -1 を返します。

サンプルコード

PHP Attribute Target Classを判定する

1<?php
2
3#[Attribute]
4class MyAttribute
5{
6    public function __construct(public string $message) {}
7}
8
9#[MyAttribute("This is a class attribute.")]
10class MyClass
11{
12    #[MyAttribute("This is a method attribute.")]
13    public function myMethod()
14    {
15        // Attribute のターゲットがクラスかどうかを判定
16        $reflection = new ReflectionAttribute($this, MyAttribute::class);
17
18        if ($reflection->getTarget() & Attribute::TARGET_CLASS) {
19            echo "Attribute is applicable to classes.\n";
20        } else {
21            echo "Attribute is not applicable to classes.\n";
22        }
23    }
24}
25
26$myClass = new MyClass();
27$myClass->myMethod();
28
29// クラスに付与された Attribute の情報を取得
30$classReflection = new ReflectionClass(MyClass::class);
31$attributes = $classReflection->getAttributes(MyAttribute::class);
32
33foreach ($attributes as $attribute) {
34    $instance = $attribute->newInstance();
35    echo "Class Attribute Message: " . $instance->message . "\n";
36}

このサンプルコードは、PHP8で導入されたAttribute機能における、Attribute::TARGET_CLASS定数の使用例を示しています。Attribute::TARGET_CLASSは、Attributeがクラスに適用可能かどうかを判定するために使用されます。

まず、MyAttributeというカスタムAttributeを定義しています。このAttributeは、コンストラクタでメッセージを受け取ります。

次に、MyClassクラスにMyAttributeを付与しています。クラス自体と、myMethodメソッドの両方にAttributeが付与されている点に注目してください。

myMethodメソッド内では、ReflectionAttributeクラスを使用して、Attributeの情報を取得しています。$reflection->getTarget()でAttributeのターゲットを取得し、ビット演算子&を用いてAttribute::TARGET_CLASS定数との論理積を計算することで、Attributeがクラスに適用可能かどうかを判定しています。もし、Attributeがクラスに適用可能であれば、「Attribute is applicable to classes.」と表示されます。そうでなければ、「Attribute is not applicable to classes.」と表示されます。

最後に、ReflectionClassクラスを使用してクラスに付与されたAttributeの情報を取得し、Attributeインスタンスを生成して、メッセージを表示しています。$classReflection->getAttributes(MyAttribute::class)は、MyClassクラスに付与されたMyAttributeの情報を配列で返します。この配列をループ処理することで、複数のAttributeの情報にアクセスできます。$attribute->newInstance()でAttributeのインスタンスを生成し、$instance->messageでコンストラクタで設定されたメッセージにアクセスできます。これにより、クラスに付与されたAttributeから情報を取得し、利用することが可能になります。

Attribute::TARGET_CLASSは、Attributeがクラスに対して適用可能かどうかを判定するための定数です。サンプルコードでは、メソッド内でクラス自身($this)に対してリフレクションを行っているため、意図した結果にならない可能性があります。Attributeのターゲットを確認する際は、ReflectionClassを使用し、クラスに付与されたAttributeに対して判定を行うようにしてください。また、ReflectionAttribute::getTarget()はビットマスクを返すため、&演算子で特定のターゲットが含まれているかを確認する必要があります。Attributeの利用にはPHP 8以降が必要です。

【PHP8.x】TARGET_CLASS定数の使い方 | いっしー@Webエンジニア