Come usare Enum in PHP 8.1

0
240

PHP 8.1 aggiungerà finalmente il supporto linguistico per gli enum. Gli enum, abbreviazione di enumerazioni, sono tipi che possono essere istanziati solo con valori specifici. Si trovano comunemente in altri linguaggi orientati agli oggetti, ma in precedenza richiedevano soluzioni per l'ambiente utente da implementare in PHP.

Sintassi di base

Qui&#8217 ;s come appare un semplice enum:

enum PostStatus { caso pubblicato; caso InReview; caso Bozza; }

La parola chiave case, precedentemente parte delle istruzioni switch, viene utilizzata per delineare i valori specifici accettati da enum. I valori sono referenziati allo stesso modo delle costanti di classe:

$pubblicato = PostStatus::Pubblicato;

Gli enum si comportano in modo simile alle classi e alle interfacce. Sono completamente compatibili con il sistema di tipi, quindi puoi digitare un suggerimento che una funzione accetta solo un valore definito in un enum:

class BlogPost {   funzione pubblica __construct( public string $Headline, public string $Content, public PostStatus $Status=PostStatus::Draft) {}   }

Ecco un esempio di utilizzo della classe BlogPost:

//OK $post = nuovo post del blog( "Post di esempio", "Un esempio", PostStatus::Draft );   //TypeError: l'argomento n. 3 ($Status) deve essere di tipo PostStatus $post = new BlogPost( “Esempio rotto”, “Un esempio rotto”, “Inviato” );

La prima istanza funziona perché $Status è un valore valido dall'enumerazione PostStatus. Nel secondo caso, viene passata una stringa semplice come $Status, il che è vietato in quanto il valore deve essere definito all'interno di PostStatus.

I casi enum sono rappresentati come costanti sull'oggetto enum. Ciò significa che puoi usarli come valori statici e come parte di espressioni costanti. Il costruttore BlogPost mostra un caso enum utilizzato come valore di parametro predefinito, dove $Status viene automaticamente impostato su Draft quando non viene fornito alcun valore dal chiamante.

Annuncio

Puoi accedere a tutti i valori disponibili in un enum usando il suo metodo case:

PostStatus::casi(); //[PostStatus::Published, PostStatus::InReview, PostStatus::Draft]

Pure vs Backed Enum

L'enum PostStatus sopra è un puro enum. Contiene solo istruzioni case, senza dati aggiuntivi. PHP consente anche di associare un valore ai casi enum, creando un enum supportato.

enum PostStatus : string { caso Pubblicato = "S1"; caso InReview = "S2"; case Bozza = "S3"; }

Qui l'enumerazione PostStatus è stata modificata per creare un'enumerazione supportata. Il typehint nella definizione dell'enum stabilisce che a ogni caso è assegnato un valore stringa. In questo esempio, supponiamo che ogni stato del post con nome abbia un identificatore breve associato. Potrebbe essere questo identificatore che viene salvato nel database quando i post vengono mantenuti.

Puoi accedere ai valori supportati tramite la proprietà value sulle istanze del caso:

class BlogPostRepository {   funzione pubblica salva(BlogPost $Post) : vuoto { $questo -> inserire( "blog_post", [ "titolo" => $Post -> Titolo, "contenuto" => $Post -> Contenuto, "stato" => $Post -> Stato -> valore ] ); }   }   $post = new BlogPost("Example", "Demo", PostStatus::Published); (nuovo BlogPostRepository()) -> salva($post);

Questo esempio imposterebbe il valore del campo di stato persistente su S1, in base alla versione supportata dell'enumerazione PostStatus mostrata sopra.

Le enumerazioni supportate accettano solo stringhe e numeri interi come valori. Non è nemmeno possibile utilizzare il tipo di unione string|int. Inoltre, ogni caso necessita di un valore univoco – il seguente esempio non è consentito:

enum PostStatus : string {   caso Pubblicato = "S1"; case Bozza = "S1";   } Pubblicità

PHP fornisce un metodo di utilità sulle enumerazioni per creare un'istanza da un valore supportato:

//recupera il post del blog precedente dal database //lo "stato" field = S1 $status = PostStatus::from($record["status"]);

Il metodo from() idraterà le istanze dai casi di valore. In questo esempio, S1 viene mappato nuovamente al caso Pubblicato e il tuo codice riceve un'istanza di PostStatus::Pubblicato.

from() genera un ValueError se il valore di input non è valido; negli scenari in cui si sa che il valore potrebbe non essere utilizzabile, è possibile utilizzare invece il metodo alternativo tryFrom(). Questo restituisce null quando non c'è corrispondenza, invece di generare l'errore.

Aggiunta di metodi agli enum

Poiché gli enum sono basati su classi, puoi anche aggiungere metodi ad essi!

enum PostStatus {   caso pubblicato; caso Bozza;   la funzione pubblica èPubliclyAccessible() : bool { restituisce ($this instanceof self::Published); }   }

Questo ti consente di mantenere il comportamento specifico del caso all'interno del tuo enum, invece di duplicarlo nella tua codebase.

Anche gli enum possono implementare interfacce:

enum PostStatus implementa PublicAccessGatable {   caso pubblicato; caso Bozza;   la funzione pubblica èPubliclyAccessible() : bool { restituisce ($this instanceof self::Published); }   }

Ora puoi passare un'istanza PostStatus a qualsiasi cosa che accetti un PublicAccessGatable:

class UserAuthenticator {   la funzione dovrebbeAllowAccess(PublicAccessGatable $Resource) : bool { restituisce ($this -> Utente -> isAdmin() || $Risorsa -> isPubliclyAccessible()); }   }   $auth = nuovo UserAuthenticator();   //ottiene un post del blog dal database se (!$auth -> shouldAllowAccess($post -> Stato)) { http_response_code(403); } Pubblicità

Non ci sono restrizioni su cosa puoi fare con i metodi enum – sono normali metodi PHP, dopotutto – ma in generale ti aspetteresti che eseguano un qualche tipo di confronto con il case dell'istanza, quindi restituiscono un valore statico. Gli enum possono usare i tratti, quindi puoi inserire anche i metodi esistenti che hai astratto in questo modo.

Puoi usare i metodi pubblici, protetti e privati ​​negli enum, anche se protected e private hanno lo stesso effetto. Gli enum non possono estendersi a vicenda, quindi il privato è effettivamente ridondante. Non puoi nemmeno aggiungere un costruttore o un distruttore. I metodi statici sono supportati e possono essere chiamati sulla classe enum o sulle sue istanze case.

Costanti

Anche le enum possono avere le proprie costanti, come valori letterali regolari o un riferimento a un caso enum:

enum PostStatus {   caso pubblicato; caso Bozza;   public const Live = self::Published; public const PlainConstant = "foobar";   }

Ciò può creare confusione poiché la stessa sintassi viene utilizzata per accedere a casi (istanze enum) e costanti:

$published = PostStatus::Published; $plain = PostStatus::PlainConstant;

Solo $published soddisferebbe un suggerimento di tipo PostStatus, poiché $plain si riferisce a un semplice valore scalare.

Quando usare Enums?

Enums sono per le occasioni in cui hai bisogno di flessibilità nel valore che una variabile può assumere, ma solo in un insieme predeterminato di casi possibili.

Pubblicità

La classe di post del blog che scorre attraverso questo post è un classico esempio I post possono essere solo in uno di un insieme noto di stati, ma PHP in precedenza non aveva un modo semplice per raggiungere questo obiettivo.

Nelle versioni precedenti, potresti aver utilizzato questo approccio:

class PostStatus { const Pubblicato = 0; const Bozza = 1; }   classe BlogPost { funzione pubblica __construct( public string $Headline, public int $Status ) {} }   $post = new BlogPost("Il mio titolo", PostStatus::Published);

Il problema qui è che $Status accetta effettivamente qualsiasi numero intero, quindi la seguente chiamata sarebbe perfettamente valida:

$post = nuovo BlogPost("Il mio titolo", 9000);

Inoltre, BlogPost e PostStatus sono completamente separati – non c'è modo che qualcuno che legge BlogPost possa apprendere l'intervallo di valori che $Status effettivamente accetta. Sebbene questi problemi possano essere mitigati utilizzando suggerimenti di tipo docblock appropriati o “false enum” di terze parti pacchetti, stanno tutti aggiungendo ulteriori livelli attorno a un concetto che altri linguaggi di programmazione rendono semplice.

L'aggiunta di enumerazioni native a PHP è un passaggio che aiuta a completare il sistema di tipi del linguaggio. Puoi finalmente digitare i valori consentiti in modo da mantenere tutti sulla stessa pagina. Se passi un valore non valido, riceverai un errore di runtime. Il tuo IDE può aiutarti meglio a fornire i valori corretti, poiché saprà che $Status accetta solo tre opzioni, invece di “qualsiasi numero intero.”

Conclusione< /h2>

Gli enum risolvono alcuni punti deboli comuni degli sviluppatori quando si lavora in PHP. Consentono di digitare il suggerimento che i parametri, i valori restituiti e le proprietà devono essere uno di un insieme di opzioni predeterminate.

Le enum sono entità di codebase flessibili che puoi mantenere semplici in forma pura o estendere con valori supportati , implementazioni dell'interfaccia e metodi personalizzati. Gli enum si comportano in modo simile agli oggetti normali nella maggior parte dei casi e supportano funzionalità di classe come __call(), __invoke e ::class.

Pubblicità

Puoi analizzare gli enum con la nuova funzione enum_exists() e ReflectionEnum Classe di riflessione. Inoltre, gli enum implementano due nuove interfacce, UnitEnum (nel caso di enum puri) e BackedEnum (per enum con valori supportati). Questi possono essere utilizzati nel codice framework generico che funziona con qualsiasi enum. Le interfacce non possono essere implementate manualmente dal codice della zona utente.

Enums arriveranno in PHP come parte della versione 8.1 a novembre 2021. Sono già disponibili nelle ultime build beta. PHP 8.1 fornirà anche molte altre funzionalità utili, incluse proprietà di sola lettura e tipi di intersezione.