PHP Conference Japan 2024

宣告屬性類別

雖然並非嚴格要求,但建議為每個屬性建立一個實際的類別。在最簡單的情況下,只需要一個空的類別,並宣告 #[Attribute] 屬性,可以使用 use 陳述式從全域命名空間導入。

範例 #1 簡單的屬性類別

<?php

namespace Example;

use
Attribute;

#[
Attribute]
class
MyAttribute
{
}

要限制可以指定屬性的宣告類型,可以將位元遮罩作為第一個參數傳遞給 #[Attribute] 宣告。

範例 #2 使用目標規範來限制屬性的使用位置

<?php

namespace Example;

use
Attribute;

#[
Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class
MyAttribute
{
}

在其他類型上宣告 MyAttribute 現在會在呼叫 ReflectionAttribute::newInstance() 時拋出例外。

可以指定以下目標:

預設情況下,一個屬性在每個宣告中只能使用一次。如果屬性應該在宣告中可重複,則必須在 #[Attribute] 宣告中將其指定為位元遮罩的一部分。

範例 #3 使用 IS_REPEATABLE 允許在宣告中多次使用屬性

<?php

namespace Example;

use
Attribute;

#[
Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION | Attribute::IS_REPEATABLE)]
class
MyAttribute
{
}
新增註釋

使用者貢獻的註釋 1 則註釋

esdras-schonevald
2 年前
#! 需要 PHP >= 8.0

#! 這是範例

<?php

declare(strict_types = 1);

#[
Attribute]
class
Foo
{
function
__construct(){
echo
"執行中 " . __METHOD__ . PHP_EOL;
}
}

#[
Attribute(Attribute::TARGET_CLASS|Attribute::IS_REPEATABLE)]
class
Bar {
function
__construct(?string ...$args){
echo
"執行中 " . __METHOD__ ,
" 參數: " . implode(", ", $args) . PHP_EOL;
}
}

#[
Attribute(Attribute::TARGET_ALL)]
class
Baz {
function
__construct(
private
string $parameter
){
echo
"執行中 " . __METHOD__ ,
" 參數: " . $this->parameter . PHP_EOL;
}
}

#[
Foo] // [0]
#[Bar] // [1]
#[Bar("香蕉")] // [2]
#[Bar("香蕉", "蘋果", "檸檬", "葡萄")] // [3]
#[Baz("唯一的一個")] // [4]
class Qux
{
}

// 使用 ReflectionClass 取得類別屬性
$ref = new ReflectionClass(Qux::class);
$attrs = $ref->getAttributes(); // 屬性陣列

$attrs[0]->newInstance(); // "執行中 Foo::__construct"
$attrs[1]->newInstance(); // "執行中 Bar::__construct 參數: "
$attrs[2]->newInstance(); // "執行中 Bar::__construct 參數: 香蕉"
$attrs[3]->newInstance(); // "執行中 Bar::__construct 參數: 香蕉, 蘋果, 檸檬, 葡萄"
$attrs[4]->newInstance(); // "執行中 Baz::__construct 參數: 唯一的一個"
To Top