PHP 8 News: Attributes

PHP 8 News: Attributes

In PHP 8, attributes (also known as annotations or metadata) were introduced as a new feature.

Attributes provide a way to add metadata to classes, methods, functions, properties, and parameters in your PHP code. They offer a standardized and declarative way to annotate code elements with additional information that can be utilized by frameworks, libraries, or custom code.

Declaration Syntax

Attributes are declared using the #[...] syntax. They can be placed directly before the declaration of a class, method, function, property, or parameter.

#[Attribute]
class MyAttribute {
    // Attribute definition
}

#[MyAttribute]
class MyClass {
    // Class definition
}

Accessing Attributes

You can access attributes using the Reflection API, allowing you to inspect the metadata attached to code elements at runtime.

$reflectionClass = new ReflectionClass('MyClass');
$classAttributes = $reflectionClass->getAttributes();

Built-in Attributes

PHP 8 comes with several built-in attributes that provide specific functionalities. Some of them include #[Deprecated], #[Final], #[Immutable], and #[Attribute] itself. These built-in attributes help in expressing the intent of the code more explicitly.

Custom Attributes

You can also define your own custom attributes by creating classes that extend the Attribute core class. This allows you to create custom metadata that fits your specific application or framework needs.

#[Attribute]
class Route {
    public function __construct(public string $path) {}
}

#[Route('/home')]
function homePage() {
    // Function definition
}

Multiple Attributes

You can apply multiple attributes to a single code element, separated by commas.

#[Route('/home')]
#[Middleware('auth')]
function homePage() {
    // Function definition
}

Attributes add a new dimension to the PHP language, allowing developers to add meaningful metadata to the source code. This not only makes it easier to write more expressive and semantic code, but also opens up new possibilities for creating more powerful and flexible tools and frameworks.

Example 1: Attributes in Classes and Methods

#[Author("Zero")]
class MyClass {
    #[Version(1.0)]
    public function myFunction() {
        // Function body
    }
}

In this example, we have a MyClass class with an Author attribute applied to the class and a Version attribute applied to the MyFunction method. These attributes can be used, for example, to document who wrote the class and what version the method is.

Example 2: Validation Attributes

class User {
    #[Required]
    public string $name;

    #[Email]
    public string $email;
}

Here, the User class has attributes such as Required and Email applied to its properties. These attributes could be used by a validation system to ensure that the name is provided and that the email is a valid email address.

Example 3: Attributes in API routes

#[Route("/users", methods: ["GET"])]
class UserController {
    #[Route("/{id}", methods: ["GET"])]
    public function getById(int $id) {
        // Search and return user by ID
    }
}

In this example, we're using attributes to define routes in an API controller. Route attributes specify the HTTP paths and methods associated with different controller actions, making route configuration more integrated into the code.

Example 4: Dependency Injection Attributes

class MyClass {
    #[Inject(Database::class)]
    private $db;

    public function __construct() {
        // Database access through dependency injection
    }
}

Here, the Inject attribute is used to specify that an instance of the Database class should be automatically injected into the $db property when an instance of MyClass is created. This facilitates dependency injection in complex applications.

Example 5: PHP Internal Attributes

class MyClass {
    #[Deprecated("This function will be removed in the next version.")]
    public function myFunction() {
        // Function body
    }
}

In this example, we're using PHP's built-in Deprecated attribute to mark a function as deprecated. This will alert developers that the function will be removed in future versions, encouraging them to update their code.

These are just a few examples of how attributes can be used in PHP 8.