PHP Conference Nagoya 2025

Syntaxe des attributs

La syntaxe des attributs comporte plusieurs parties. Tout d'abord, une déclaration d'attribut est toujours entourée d'un #[ et d'une terminaison correspondante ]. À l'intérieur, un ou plusieurs attributs séparés par une virgule sont énumérés. Le nom de l'attribut est un nom non qualifié, qualifié ou pleinement qualifié, comme décrit dans la section Utilisation des espaces de noms : introduction. Les arguments de l'attribut sont facultatifs, mais ils sont placés entre les parenthèses habituelles (). Les arguments des attributs ne peuvent être que des valeurs littérales ou des expressions constantes. Les syntaxes des arguments positionnels et nommés peuvent toutes deux être utilisées.

Les noms d'attributs et leurs arguments sont résolus à une classe et les arguments sont transmis à son constructeur lorsqu'une instance de l'attribut est demandée par l'intermédiaire de l'API de réflexion. Ainsi une classe doit être introduite pour chaque attribut.

Exemple #1 Syntaxe des attributs

<?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
4
yarns dot purport0n at icloud dot com
11 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