PHP 8 News: Attributes
Tags: php
Published: 2024-02-24 22:25:33

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.

```php
#[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.

```php
$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.

```php
#[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.

```php
#[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

```php
#[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

```php
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

```php
#[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

```php
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

```php
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`.