CascadiaPHP 2024

Syntax von Attributen

Die Syntax von Attributen besteht aus mehreren Teilen. Zunächst wird eine Attributdeklaration immer mit einem öffnenden #[ und einem dazugehörigen abschließenden ] umschlossen. Darin werden ein oder mehrere Attribute durch Komma getrennt aufgelistet. Die Attribute können mit unqualifizierten, qualifizierten oder vollqualifizierten Namen angegeben werden, wie es in den Grundlagen der Verwendung von Namespaces beschrieben ist. Die Argumente für ein Attribut sind optional und werden in einer normalen Klammer () eingeschlossen. Die Argumente für Attribute können nur Literalwerte oder konstante Ausdrücke sein. Es kann sowohl die Syntax für positionale als auch für benannte Argumente verwendet werden.

Wenn ein Attribut über die Reflection-API angefordert wird, wird sein Name wie ein Klassenname behandelt und seine Argumente werden an seinen Konstruktor übergeben. Für jedes Attribut muss also eine entsprechende Klasse existieren.

Beispiel #1 Syntax von Attributen

<?php
// a.php
namespace MyExample;

use
Attribute;

#[
Attribute]
class
MyAttribute
{
const
VALUE = 'value';

private
$value;

public function
__construct($value = null)
{
$this->value = $value;
}
}

// b.php

namespace Another;

use
MyExample\MyAttribute;

#[
MyAttribute]
#[
\MyExample\MyAttribute]
#[
MyAttribute(1234)]
#[
MyAttribute(value: 1234)]
#[
MyAttribute(MyAttribute::VALUE)]
#[
MyAttribute(array("key" => "value"))]
#[
MyAttribute(100 + 200)]
class
Thing
{
}

#[
MyAttribute(1234), MyAttribute(5678)]
class
AnotherThing
{
}
add a note

User Contributed Notes 1 note

up
3
yarns dot purport0n at icloud dot com
6 months ago
It wasn't obvious to me for a while but you can subclass attributes

https://3v4l.org/TrMTe

<?php

#[Attribute(Attribute::TARGET_PROPERTY)]
class
PropertyAttributes
{
public function
__construct(
public readonly ?
string $name = null,
public readonly ?
string $label = null,
) {}
}

#[
Attribute(Attribute::TARGET_PROPERTY)]
class
IntegerPropertyAttributes extends PropertyAttributes
{
public function
__construct(
?
string $name = null,
?
string $label = null,
public readonly ?
int $default = null,
public readonly ?
int $min = null,
public readonly ?
int $max = null,
public readonly ?
int $step = null,
) {
parent::__construct($name, $label);
}
}

#[
Attribute(Attribute::TARGET_PROPERTY)]
class
FloatPropertyAttributes extends PropertyAttributes
{
public function
__construct(
?
string $name = null,
?
string $label = null,
public readonly ?
float $default = null,
public readonly ?
float $min = null,
public readonly ?
float $max = null,
) {
parent::__construct($name, $label);
}
}

class
MyClass
{
#[
IntegerPropertyAttributes('prop', 'property: ', 5, 0, 10, 1)]
public
int $prop;
}

$refl = new ReflectionProperty('MyClass', 'prop');
$attributes = $refl->getAttributes();

foreach (
$attributes as $attribute) {
var_dump($attribute->getName());
var_dump($attribute->getArguments());
var_dump($attribute->newInstance());
}
?>
To Top