PHP Attributes
In this page:
#[Attribute]
class AttributeName {
public function __construct(public type $property) {}
}
#[AttributeName(value)]
class ClassName { }
What are Attributes?
Attributes, introduced in PHP 8.0, let you attach structured metadata directly to classes, methods, and properties in native PHP syntax, replacing what used to require parsing PHPDoc comments as plain text.
Example: What are Attributes?
<?php
#[Attribute]
// Define the class `Route`
class Route {
// Define the constructor `__construct` taking `public string $path`
public function __construct(public string $path) {}
}
#[Route('/home')]
class HomeController {}
// Print "Attributes attach structured metadata directly in PHP syntax" to the output
echo "Attributes attach structured metadata directly in PHP syntax";
?>
Login to try C/C++/Java/PHP code in the editor
Defining custom Attributes
Defining a custom attribute is just defining a normal class and marking it with the built-in #[Attribute] annotation, which tells PHP this class is meant to be used as metadata rather than instantiated directly in the usual way.
Example: Defining custom Attributes
<?php
#[Attribute]
// Define the class `Deprecated`
class Deprecated {
// Define the constructor `__construct` taking `public string $reason`
public function __construct(public string $reason = '') {}
}
// Print "Deprecated is now usable as an attribute" to the output
echo "Deprecated is now usable as an attribute";
?>
Login to try C/C++/Java/PHP code in the editor
Applying Attributes
Applying an attribute means writing #[YourAttribute] directly above the class, method, or property it describes -- the syntax is compact and lives right alongside the code it annotates.
Example: Applying Attributes
<?php
#[Attribute]
// Define the class `Deprecated`
class Deprecated {
// Define the constructor `__construct` taking `public string $reason`
public function __construct(public string $reason = '') {}
}
// Define the class `Report`
class Report {
#[Deprecated('Use generate() instead')]
// Define the function `oldGenerate` with no parameters
function oldGenerate() {}
}
// Print "Attribute applied directly above the method" to the output
echo "Attribute applied directly above the method";
?>
Login to try C/C++/Java/PHP code in the editor
Reading Attributes with Reflection
Attributes are inert until read: the Reflection API's getAttributes() method retrieves them at runtime, which is how frameworks use attributes to drive behavior like route registration or validation rules.
Example: Reading Attributes with Reflection
<?php
#[Attribute]
// Define the class `Route`
class Route {
// Define the constructor `__construct` taking `public string $path`
public function __construct(public string $path) {}
}
#[Route('/home')]
class HomeController {}
// Create a new `ReflectionClass` instance with `HomeController::class`, stored in `$reflection`
$reflection = new ReflectionClass(HomeController::class);
// Declare `$attributes`, set to `$reflection->getAttributes(Route::class)`
$attributes = $reflection->getAttributes(Route::class);
// Print `$attributes[0]->newInstance()->path` to the output
echo $attributes[0]->newInstance()->path;
?>
Login to try C/C++/Java/PHP code in the editor
Attributes vs. PHPDoc
Because attributes are parsed and validated by the PHP engine itself rather than by a separate documentation-comment parser, they're both faster to read and far less prone to silent typos than PHPDoc annotations.
Example: Attributes vs. PHPDoc
<?php
// PHPDoc (parsed as a comment, not validated by PHP):
// /** @route /home */
// Attribute (parsed and validated by the engine itself):
#[Attribute]
class Route {
public function __construct(public string $path) {}
}
echo "Attributes are engine-native, PHPDoc is just a comment convention";
?>
Login to try C/C++/Java/PHP code in the editor
- Expecting an attribute to do something on its own, when it only stores metadata that code must read with Reflection.
- Using attributes on PHP older than 8.0, where
#[...]is treated as a comment. - Forgetting the
#[Attribute]marker on a custom attribute class, so it cannot be used as an attribute.
Chapter Quiz — Complete all 24 topics to unlock
0/24 topics done
Complete these topics first:
- PHP Date & Time
- PHP Math Functions
- PHP JSON Handling
- PHP XML Handling
- PHP cURL Introduction
- PHP REST API Basics
- PHP Composer & Packages
- PHP Autoloading
- PHP Design Patterns
- PHP MVC Architecture
- PHP Security Best Practices
- PHP Performance Optimization
- PHP 8 New Features
- PHP Type Declarations
- PHP Match Expression Advanced
- PHP Fibers
- PHP Attributes
- PHP Magic Constants
- PHP Include & Require
- PHP Iterables
- PHP SimpleXML Parser
- PHP SimpleXML Get
- PHP XML Expat Parser
- PHP DOM Parser