Menu

Enum PHP : backed enums, from(), tryFrom() et cases()

Une enum PHP (8.1+) est un type avec une liste fixe de valeurs : enum Status: string { case Active = 'active'; }. Enums pures et enums adossées, ->value et ->name, conversion avec from() et tryFrom(), liste des cases avec cases(), méthodes, constantes, interfaces et enums dans match.

Cette page contient des éditeurs exécutables - modifiez, exécutez et voyez la sortie instantanément.

Une enum PHP (PHP 8.1+) définit un type avec un ensemble fixe de valeurs possibles, ses cases : enum Status { case Active; case Banned; }. Vous utilisez un case sous la forme Status::Active, et un paramètre typé Status n'accepte rien d'autre. Une enum adossée (backed enum), enum Status: string, donne aussi à chaque case une valeur que vous pouvez stocker et reconvertir avec Status::from().

Avant les enums, on utilisait une liste de constantes de type chaîne, et rien n'empêchait une faute de frappe comme 'actve' d'atteindre la base de données. Avec Status comme type de paramètre, seuls les trois cases peuvent être passés.

Enums pures et enums adossées

Une enum pure a des cases qui ne sont que des noms. Une enum adossée déclare un type après le nom, int ou string, et chaque case doit alors avoir une valeur unique de ce type. Chaque case a ->name ; seuls les cases adossés ont ->value.

Prenez une enum adossée chaque fois que la valeur sort du programme : une colonne de base de données, une URL, un champ de formulaire, du JSON. Prenez une enum pure pour les valeurs qui n'existent que dans le code, comme l'état d'un analyseur.

Convertir une valeur avec from() et tryFrom()

Les enums adossées reçoivent deux méthodes statiques pour retransformer une valeur stockée en case. from() lève une ValueError pour une valeur inconnue ; tryFrom() renvoie null, ce qui se combine bien avec ?? pour une valeur par défaut :

Utilisez tryFrom() sur tout ce qu'un utilisateur vous a envoyé, et from() sur les valeurs que votre propre code a écrites, où une valeur inconnue signale un bug dont vous voulez être averti. L'argument suit les règles normales de type des paramètres : sur une enum int, Priority::from('5') renvoie Priority::Normal en mode par défaut car '5' est d'abord converti en 5, Priority::from('5x') est une TypeError, et avec declare(strict_types=1) toute chaîne est une TypeError. Cela vaut aussi pour tryFrom() : Priority::tryFrom('abc') lève une erreur au lieu de renvoyer null, vérifiez donc d'abord une saisie de formulaire destinée à une enum int avec filter_var($raw, FILTER_VALIDATE_INT).

Lister tous les cases avec cases()

Enum::cases() renvoie un tableau de tous les cases, dans l'ordre de déclaration. C'est ainsi qu'on construit une liste déroulante, qu'on valide une liste ou qu'on obtient toutes les valeurs avec array_column :

Exécutez-le, choisissez une offre et cliquez sur Choose : le même script s'exécute à nouveau avec $_POST['plan'] rempli, et tryFrom() retransforme la chaîne envoyée en case Plan. Une valeur falsifiée comme plan=gold donne null, et aucune option n'est sélectionnée.

Méthodes, constantes et interfaces d'enum

Les enums peuvent avoir des méthodes, des méthodes statiques et des constantes, et implémenter des interfaces. Dans une méthode, $this est le case courant, ce qui fait de match ($this) la façon naturelle d'associer des données à chaque case. Ce qu'une enum ne peut pas avoir, ce sont des propriétés : les données propres à chaque case viennent de méthodes.

Les enums dans match

match compare avec ===, et un case n'est identique qu'à lui-même, donc match et les enums vont bien ensemble. Si vous oubliez un case et que ce case atteint le match, PHP lève une UnhandledMatchError au lieu de ne rien renvoyer en silence :

Voir match pour la différence entre match et switch.

Les enums en JSON et en chaîne

json_encode() écrit un case adossé sous forme de sa valeur. Une enum pure ne peut pas être encodée, et un echo de n'importe quel case échoue, car une enum est un objet, pas une chaîne. Affichez plutôt ->value ou ->name :

echo Role::Admin; lève une Error (« Object of class Role could not be converted to string »), et les enums ne peuvent pas implémenter __toString(). Au retour, le JSON donne une simple chaîne, convertissez-la donc avec from() ou tryFrom() comme montré. L'encodage est détaillé dans json_encode.

Erreurs fréquentes avec les enums

Trois erreurs reviennent sans cesse. Un case n'est jamais égal à sa valeur, un case ne peut pas être une clé de tableau, et new ne fonctionne pas sur une enum :

S'il vous faut une table indexée par les cases eux-mêmes, utilisez SplObjectStorage ou WeakMap, qui acceptent des objets comme clés.

Questions fréquentes

Comment obtenir la valeur d'une enum en PHP ?

Sur une enum adossée, lisez ->value : Status::Active->value vaut 'active'. Chaque case a aussi ->name, le nom du case sous forme de chaîne ('Active'). Une enum pure (sans : string ni : int) n'a que ->name.

Quelle est la différence entre from() et tryFrom() pour les enums PHP ?

Les deux transforment une valeur en case d'une enum adossée. Status::from('active') renvoie le case ou lève une ValueError quand aucun case n'a cette valeur ; Status::tryFrom('nope') renvoie null à la place. Utilisez tryFrom() pour une saisie utilisateur et from() quand une mauvaise valeur est un bug.

Comment obtenir toutes les valeurs d'une enum en PHP ?

Status::cases() renvoie tous les cases dans l'ordre de déclaration. Pour les valeurs d'une enum adossée, utilisez array_column(Status::cases(), 'value'), et pour les noms array_column(Status::cases(), 'name').

Quelle est la différence entre une enum pure et une enum adossée ?

Une enum pure (enum Suit { case Hearts; }) a des cases qui ne sont que des noms. Une enum adossée (enum Suit: string { case Hearts = 'H'; }) donne à chaque case une valeur int ou string unique, nécessaire pour la stocker en base de données, la mettre dans un formulaire ou du JSON, et la reconvertir avec from() ou tryFrom().

Une enum PHP peut-elle avoir des méthodes ?

Oui. Les enums peuvent avoir des méthodes, des méthodes statiques et des constantes, et implémenter des interfaces. Dans une méthode, $this est le case courant, donc return match ($this) { self::Active => 'green', self::Banned => 'red' }; est un modèle courant. Les enums ne peuvent pas avoir de propriétés.

Illustration des langages de programmation de Coddy

Apprendre à coder avec Coddy

COMMENCER