Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

PHP Attributes (introduced in PHP 8.0) provide a native, structured syntax for embedding machine-readable metadata directly into code declarations. They replace docblock annotations by allowing developers to associate configuration, state, or behavioral directives with classes, methods, properties, parameters, functions, and class constants. This metadata is inert by default and must be explicitly inspected and instantiated at runtime using the PHP Reflection API. Attributes are declared using the #[...] syntax and can accept zero or more arguments, which are passed to the underlying attribute class constructor.
#[SimpleAttribute]
#[AttributeWithArguments('value', key: 'value')]
class TargetClass {}

Creating Custom Attributes

Under the hood, an attribute is simply a standard PHP class. To designate a class as a valid attribute, it must be annotated with the built-in #[Attribute] attribute. The constructor of this class dictates the signature of the arguments that can be passed when the attribute is applied.
#[Attribute]
class SystemMetadata {
    public function __construct(
        public readonly string $identifier,
        public readonly int $version = 1
    ) {}
}

Applying Attributes

Once defined, the attribute can be applied to various structural elements in PHP. Multiple attributes can be applied to the same declaration, either grouped within the same brackets or stacked.
#[SystemMetadata(identifier: 'core_module', version: 2)]
class ModuleManager {
    
    #[SystemMetadata('init_flag')]
    #[AnotherAttribute]
    public bool $isInitialized;

    #[SystemMetadata('boot_sequence')]
    public function boot(
        #[SystemMetadata('config_array')] array $config
    ): void {}
}

Restricting Attribute Targets

By default, a custom attribute can be applied to any declaration. You can restrict where an attribute is syntactically valid by passing bitmask flags to the base #[Attribute] declaration using predefined constants from the Attribute class. Available target flags include:
  • Attribute::TARGET_CLASS
  • Attribute::TARGET_FUNCTION
  • Attribute::TARGET_METHOD
  • Attribute::TARGET_PROPERTY
  • Attribute::TARGET_CLASS_CONSTANT
  • Attribute::TARGET_PARAMETER
  • Attribute::TARGET_ALL (Default)
#[Attribute(Attribute::TARGET_METHOD | Attribute::TARGET_FUNCTION)]
class ExecutableMetadata {}

Repeatable Attributes

By default, a specific attribute can only be applied to a given declaration once. To allow multiple instances of the same attribute on a single declaration, the Attribute::IS_REPEATABLE flag must be combined with the target flags.
#[Attribute(Attribute::TARGET_CLASS | Attribute::IS_REPEATABLE)]
class Tag {
    public function __construct(public string $tagName) {}
}

#[Tag('core')]
#[Tag('service')]
class TaggedService {}

Resolving Attributes via Reflection

Attributes do not execute automatically. To read and utilize attribute data, you must use the Reflection API. Reflection classes (e.g., ReflectionClass, ReflectionMethod, ReflectionProperty) provide the getAttributes() method, which returns an array of ReflectionAttribute objects. The ReflectionAttribute object contains the metadata about the attribute but does not immediately instantiate the underlying attribute class. You must call newInstance() to invoke the attribute’s constructor and receive the actual class instance.
$reflection = new ReflectionClass(ModuleManager::class);

// Retrieve specific attributes by passing the class name
$attributes = $reflection->getAttributes(SystemMetadata::class);

foreach ($attributes as $reflectionAttribute) {
    // $reflectionAttribute->getName() returns the attribute class name
    // $reflectionAttribute->getArguments() returns the raw arguments array
    
    // Instantiate the actual SystemMetadata class
    $metadataInstance = $reflectionAttribute->newInstance();
    
    echo $metadataInstance->identifier; // Outputs: core_module
    echo $metadataInstance->version;    // Outputs: 2
}
Master PHP with Deep Grasping Methodology!Learn More