
Intro a PHP 8
alberto • October 26, 2020
PHPSecondo articolo dedicato alla prossima release di PHP. In questo articolo introduciamo una nuova features particolarmente interessate ed abilitante: gli attributes.
Annotation? Attributes!
Gli attributes in PHP rappresentano esattamente quei meta-dati che in altri linguaggi prendono il nome di Annotations.
Con meta-dati intendiamo un nuovo elemento all'interno delle nostri classi che permettono di arricchire con delle caratteristiche particolari i nostri elementi di programmazione. Un attribute può infatti essere associato a:
- funzioni
- parametri di funzioni
- classi
- interfacce
- traits
- costanti
- proprietà
- metodi
- parametri di metodi
E' opportuno ricordare che un attributo, di per sè, non fa niente, è una sorta di placeholder che viene utilizzato da altri componenti che, sfruttando la introspection, analizzano le classi e le utilizzano in qualche modo.
Proviamo a fare un esempio in ambito Laravel.
Un ipotetico esempio Laravel-Way
Nota bene: l'esempio descritto non funziona, è solamente una ipotesi su come potrebbe essere implementata una funzionalità in Laravel
Come ben sappiamo, i file di rotte spesso si occupano di associare una determinata url (e relativo metodo HTTP) ad un metodo all'interno di una classe controller.
Proviamo ad immagine come potremmo riscrivere questo mapping tramite gli Attributes.
<<Controller(['prefix' => '/posts'])>>
class PostController
{
<<RouteMethod(['url' => '/', 'method' => 'GET'])>>
public function getList()
{
[...]
}
<<RouteMethod(['url' => '/', 'method' => 'GET'])>>
public function getDetail(Post $post)
{
[...]
}
}
In questo esempio, che ripeto essere non funzionante, stiamo utilizzando due attributes di esempio (Controller
e RouteMethod
) per decorare una nostra classe ed alcuni metodi con alcuni meta-dati. L'engine di routing di Laravel potrebbe analizzare queste classi e creare una alberatura di rotte automaticamente leggendo questi file, senza la necessità di creare un file php dedicato (come avviene ora).
Creare ed utilizzare Attributes
Una volta compreso bene quali sono le potenzialità degli attributes, potrebbe aver senso capire come possono essere creati ed utilizzati.
Un attributo non è nient'altro che una classe che viene utilizzata appunto a questo scopo e non come classe istanziabile:
namespace App\Attributes;
use PhpAttribute;
<<PhpAttribute>>
class CustomAttribute
{
public $options;
public function __construct(array $options)
{
$this->options = $options;
}
}
In questo caso abbiamo creato un attributo che riceve un array di opzioni come parametro. È comunque possibile creare attributi senza parametri o con più di un parametro, esattamente come una classe normale.
Per assegnare questo attributo ad una classe basta referenziare la dipendenza nel modo tradizionale:
namespace App\Services;
use App\Attributes\CustomAttribute;
<<CustomAttribute>>
class MyService
{
[...]
}
Seppure questa è una implementazione completamente funzionante, non è sufficente per aggiungere nuove funzionalità alle nostre classi. Per poterlo fare è necessario utilizzare un componente in grado di leggere l'attribute e sfruttare questo meta-dato.
Per accedere a questi dati, PHP 8 introduce i seguenti nuovi metodi nel modulo di reflection:
function ReflectionFunction::getAttributes(string $name = null, int $flags = 0): ReflectionAttribute[];
function ReflectionClass::getAttributes(string $name = null, int $flags = 0): ReflectionAttribute[];
function ReflectionProperty::getAttributes(string $name = null, int $flags = 0): ReflectionAttribute[];
function ReflectionClassConstant::getAttributes(string $name = null, int $flags = 0): ReflectionAttribute[];
Grazie ad essi possiamo ottenere la lista di attributi associati rispettivamente a funzioni, classi, property e costanti.
Riprendendo l'esempio di prima, un possibile utilizzo potrebbe essere questo:
$reflectionClass = new \ReflectionClass(App\Services\MyService::class);
$attributes = $reflectionClass->getAttributes();
var_dump($attributes);
Abbastanza confuso?
Credo sia parecchio normale. Gli Attributes, cosi come le Annotations di altri linguaggi, vengono compresi solamente con l'utilizzo quotidiano.
Difficilmente uno sviluppatore andrà ad implementare gli Attribute all'interno della propria applicazione. Il caso d'uso tipico è quello di un framework o di una libreria che, per implementare una determinata funzionalità, utilizza gli attributi, un po' come l'esempio, ipotetico, visto sopra.
Sicuramente la community PHP sfrutterà tutte le potenzialità di questo nuovo strumento per rendere le nostre classi consistenti ed auto-documentate senza la necessità di creare mapping o file di configurazioni fuori contesto.