Dans cet article
- Les php enum sont disponibles nativement depuis PHP 8.1, sorti en novembre 2021
- Il existe deux types d’énumérations : les Pure Enums (sans valeur) et les Backed Enums (avec valeur string ou int)
- Les enums PHP implémentent des interfaces et supportent les traits, ce qui les rend plus puissants qu’une simple liste de constantes
- La méthode from() et tryFrom() permettent de convertir une valeur scalaire en cas d’énumération de façon sécurisée
- Avec Symfony et Doctrine, les enum php s’intègrent nativement depuis Symfony 6.1 et Doctrine ORM 2.11
- Les enums remplacent avantageusement les constantes de classe et les faux patterns d’énumération utilisés avant PHP 8.1
Sommaire
- Qu’est-ce qu’un enum en PHP ?
- Pure Enum vs Backed Enum : comprendre les deux types
- Comment définir et utiliser une énumération en PHP
- Méthodes, interfaces et traits dans les enums
- Différences entre enum et class en PHP
- Cas pratiques : enum string, match et vérification de valeur
- Utiliser les enums avec Symfony et Doctrine
- Bonnes pratiques et pièges à éviter
Avant PHP 8.1, je devais bricoler des constantes de classe ou des bibliothèques tierces pour simuler un comportement d’énumération. Depuis novembre 2021, le mot-clé enum fait officiellement partie du langage. Si vous préparez votre BTS SIO ou si vous travaillez sur un projet professionnel, comprendre les php enum est désormais indispensable. Je vous propose un tour complet du sujet, du concept de base jusqu’à l’intégration avec Symfony.
Qu’est-ce qu’un enum en PHP ?
Un enum php (abréviation d’énumération) est un type de données qui restreint une variable à un ensemble fini de valeurs prédéfinies. Concrètement, au lieu d’utiliser des chaînes de caractères ou des entiers arbitraires pour représenter un statut, une couleur ou un rôle, vous déclarez un type dédié qui ne peut prendre que les valeurs que vous avez explicitement listées.
C’est quoi le type enum, exactement ? Pensez à un feu tricolore : il ne peut être que rouge, orange ou vert. Un enum modélise précisément cette contrainte dans votre code. Si quelqu’un tente d’assigner une valeur qui n’existe pas dans l’énumération, PHP lèvera une erreur. C’est un filet de sécurité que les simples constantes ne fournissent pas.

Les énumérations existent dans de nombreux langages : Java, C#, TypeScript, Rust ou Python les proposent depuis longtemps. PHP a rejoint cette liste avec la RFC officielle des enums dans PHP 8.1. Cette fonctionnalité a été l’une des plus attendues par la communauté PHP, et elle change réellement la façon dont on structure le code métier.
Quelle version de PHP utilise enum ? Les énumérations nécessitent PHP 8.1 minimum. Si votre serveur tourne encore sur PHP 8.0 ou une version antérieure, vous devrez mettre à jour votre environnement avant de pouvoir utiliser cette fonctionnalité. Je recommande d’ailleurs de cibler au minimum PHP 8.2 en 2026 pour bénéficier des dernières améliorations de stabilité.
Pure Enum vs Backed Enum : comprendre les deux types
PHP propose deux catégories d’énumérations, et le choix entre les deux dépend de votre besoin de persistance ou de sérialisation.
Les Pure Enums (énumérations unitaires)
Un Pure Enum ne porte aucune valeur scalaire. Chaque cas est une instance unique du type, sans représentation string ou int associée. Voici un exemple simple :
enum Couleur {
case Rouge;
case Vert;
case Bleu;
}
Ce type d’enum convient parfaitement quand vous n’avez pas besoin de stocker la valeur en base de données ni de la transmettre via une API. Il sert de type-hint strict dans vos signatures de fonctions.
Les Backed Enums (énumérations à valeur de base)
Un Backed Enum associe chaque cas à une valeur string ou int. C’est le choix que je recommande dans la majorité des projets, car vous aurez presque toujours besoin de persister ces valeurs :
enum Statut: string {
case Brouillon = 'brouillon';
case Publie = 'publie';
case Archive = 'archive';
}
enum Priorite: int {
case Basse = 1;
case Moyenne = 2;
case Haute = 3;
}
Avec un Backed Enum, chaque cas expose une propriété ->value qui retourne la valeur scalaire associée. C’est cette valeur que vous stockerez en base ou transmettrez dans vos réponses JSON.
| Caractéristique | Pure Enum | Backed Enum |
|---|---|---|
| Valeur scalaire associée | Non | Oui (string ou int) |
Propriété ->value |
Non disponible | Disponible |
Méthode from() / tryFrom() |
Non disponible | Disponible |
| Stockage en base de données | Nécessite un mapping manuel | Directement via la valeur |
| Cas d’usage typique | Typage interne, pattern matching | API, BDD, formulaires |
| Interface implémentée automatiquement | UnitEnum | BackedEnum (étend UnitEnum) |
Comment définir et utiliser une énumération en PHP
Comment définir une énumération en PHP ? La syntaxe est volontairement proche de celle des classes, ce qui la rend intuitive pour tout développeur PHP. Voici la marche à suivre étape par étape.
Déclaration de base
enum Role: string {
case Admin = 'admin';
case Editeur = 'editeur';
case Lecteur = 'lecteur';
}
Le mot-clé enum remplace class. Chaque valeur possible est introduite par le mot-clé case. Si vous ajoutez un type après le nom (ici : string), vous créez un Backed Enum et chaque cas doit obligatoirement avoir une valeur assignée.
Utiliser un enum comme type-hint
function attribuerRole(Utilisateur $user, Role $role): void {
$user->role = $role;
}
// Appel correct
attribuerRole($user, Role::Admin);
// Erreur fatale : un string n'est pas un Role
attribuerRole($user, 'admin');
C’est là toute la puissance des énumérations : le typage strict empêche les erreurs à l’exécution. Fini les fautes de frappe sur des chaînes de caractères qui passent inaperçues en production. Si vous utilisez déjà les structures conditionnelles comme le switch en PHP, vous verrez que les enums s’y combinent parfaitement.

Accéder à la valeur et au nom
$statut = Statut::Publie;
echo $statut->value; // "publie"
echo $statut->name; // "Publie"
La propriété name est disponible sur tous les enums (Pure et Backed). Elle retourne le nom du cas tel que déclaré dans le code. La propriété value n’est disponible que sur les Backed Enums.
Convertir une valeur en enum : from() et tryFrom()
Comment utiliser enum pour récupérer un cas à partir d’une valeur issue d’un formulaire ou d’une base de données ? PHP fournit deux méthodes statiques :
// Lève une ValueError si la valeur n'existe pas
$statut = Statut::from('publie'); // Statut::Publie
// Retourne null si la valeur n'existe pas
$statut = Statut::tryFrom('inconnu'); // null
J’utilise tryFrom() systématiquement quand la donnée provient de l’extérieur (requête HTTP, fichier CSV, API tierce). C’est une approche défensive qui évite les exceptions non gérées. La méthode from() convient quand vous êtes certain que la valeur est valide, par exemple après une validation préalable.
Lister tous les cas
$tousLesStatuts = Statut::cases();
// Retourne un tableau de tous les cas : [Statut::Brouillon, Statut::Publie, Statut::Archive]
La méthode cases() est très utile pour générer des listes déroulantes dans vos formulaires ou pour valider qu’une valeur appartient bien à l’énumération.
Méthodes, interfaces et traits dans les enums
Les enum php ne sont pas de simples listes statiques. Ils supportent des méthodes, peuvent implémenter des interfaces et utiliser des traits, ce qui en fait un outil de modélisation très expressif.
Ajouter des méthodes
enum Statut: string {
case Brouillon = 'brouillon';
case Publie = 'publie';
case Archive = 'archive';
public function label(): string {
return match($this) {
self::Brouillon => 'En brouillon',
self::Publie => 'Publié',
self::Archive => 'Archivé',
};
}
public function estVisible(): bool {
return $this === self::Publie;
}
}
echo Statut::Publie->label(); // "Publié"
L’expression match fonctionne remarquablement bien avec les enums. Si vous oubliez un cas, PHP vous le signalera, ce qui renforce la fiabilité du code. Cette approche est très proche du php case statement classique, mais avec une syntaxe plus concise et un contrôle de type plus strict.
Implémenter une interface
interface ALabel {
public function label(): string;
}
enum Priorite: int implements ALabel {
case Basse = 1;
case Moyenne = 2;
case Haute = 3;
public function label(): string {
return match($this) {
self::Basse => 'Priorité basse',
self::Moyenne => 'Priorité moyenne',
self::Haute => 'Priorité haute',
};
}
}
Grâce aux interfaces, vous pouvez manipuler différents enums de façon polymorphe. C’est particulièrement utile quand plusieurs énumérations doivent exposer un label lisible ou un comportement commun.
Utiliser des traits
Les enums ne peuvent pas avoir de propriétés d’instance (pas de $this->maVariable), mais ils peuvent utiliser des traits contenant des méthodes. Cela permet de mutualiser du comportement entre plusieurs enums sans dupliquer le code.
Les constantes dans les enums
Pour ceux qui cherchent php enum constants, sachez qu’un enum peut contenir des constantes classiques en plus de ses cas :
enum Saison: string {
case Printemps = 'printemps';
case Ete = 'ete';
case Automne = 'automne';
case Hiver = 'hiver';
const DEFAUT = self::Printemps;
}
$s = Saison::DEFAUT; // Saison::Printemps
Cette technique est pratique pour définir une valeur par défaut tout en gardant la rigueur du typage enum.
Différences entre enum et class en PHP
Quelle est la différence entre enum et class en PHP ? La question revient souvent, et la réponse tient en quelques points fondamentaux.
Un enum est un type fermé : vous ne pouvez pas ajouter de nouveaux cas à l’exécution, et chaque cas est un singleton. En revanche, une classe est un type ouvert : vous pouvez l’instancier autant de fois que nécessaire avec des propriétés différentes.
| Aspect | Enum | Classe |
|---|---|---|
| Instanciation | Impossible (cas prédéfinis uniquement) | Libre via new |
| Propriétés d’instance | Interdites | Autorisées |
| Héritage | Interdit (pas d’extends) |
Supporté |
| Interfaces | Supportées via implements |
Supportées via implements |
| Traits | Supportés (sans propriétés) | Supportés (avec propriétés) |
| Méthodes | Supportées | Supportées |
| Sérialisation | Spécifique (pas Serializable) |
Complète |
| Comparaison | === compare l’identité du cas |
=== compare la référence objet |

En pratique, utilisez un enum quand l’ensemble des valeurs possibles est connu à l’avance et ne changera pas à l’exécution. Si vos valeurs sont dynamiques (stockées en BDD et modifiables par un administrateur), une classe ou un modèle reste plus adapté. L’enum excelle pour les statuts, les rôles, les types de paiement, les jours de la semaine ; bref, tout ce qui est structurellement fini.
Avant PHP 8.1, on simulait souvent les enums avec des classes abstraites contenant des constantes. Cette approche, bien que fonctionnelle, ne fournissait aucune vérification de type. On pouvait passer n’importe quel entier là où seul un statut valide était attendu. Le php-enum natif résout ce problème à la racine.
Cas pratiques : enum string, match et vérification de valeur
Passons aux situations concrètes que vous rencontrerez au quotidien.
PHP enum string : mapper un enum vers l’affichage
Le cas le plus fréquent consiste à associer chaque valeur d’un php enum string à un libellé humain. L’expression match est votre meilleur allié ici :
enum TypePaiement: string {
case CarteBancaire = 'cb';
case Virement = 'virement';
case Cheque = 'cheque';
case Especes = 'especes';
public function label(): string {
return match($this) {
self::CarteBancaire => 'Carte bancaire',
self::Virement => 'Virement bancaire',
self::Cheque => 'Chèque',
self::Especes => 'Espèces',
};
}
public function icone(): string {
return match($this) {
self::CarteBancaire => 'credit-card',
self::Virement => 'bank',
self::Cheque => 'file-text',
self::Especes => 'dollar-sign',
};
}
}
Ce pattern php enum match centralise la logique de présentation directement dans l’enum. Plus besoin de structures switch imbriquées dispersées dans le code.
PHP enum check if value exists
Pour vérifier si une valeur correspond à un cas valide de l’énumération, la méthode tryFrom() est la solution idiomatique :
function estStatutValide(string $valeur): bool {
return Statut::tryFrom($valeur) !== null;
}
estStatutValide('publie'); // true
estStatutValide('supprime'); // false
Vous pouvez aussi parcourir les cas pour une logique plus avancée :
function valeurExiste(string $valeur): bool {
foreach (Statut::cases() as $cas) {
if ($cas->value === $valeur) {
return true;
}
}
return false;
}
PHP enum get value : récupérer la valeur sous-jacente
Pour obtenir la valeur scalaire d’un cas, utilisez simplement la propriété ->value. Pour construire un tableau associatif nom/valeur, voici une approche concise :
$map = array_column(Statut::cases(), 'value', 'name');
// ['Brouillon' => 'brouillon', 'Publie' => 'publie', 'Archive' => 'archive']
Cette technique est idéale pour alimenter un select HTML ou pour construire une réponse API listant les valeurs acceptées. Si vous travaillez avec des tableaux, notez que les fonctions comme sizeof en PHP fonctionnent aussi sur le résultat de cases().
Utiliser un enum dans un match ou switch
$statut = Statut::from($request->input('statut'));
$message = match($statut) {
Statut::Brouillon => 'Votre article est en cours de rédaction.',
Statut::Publie => 'Votre article est en ligne.',
Statut::Archive => 'Votre article a été archivé.',
};
Avec match, PHP vérifie l’exhaustivité : si vous ajoutez un nouveau cas à l’enum sans mettre à jour le match, une UnhandledMatchError sera levée. C’est un garde-fou précieux que le switch classique ne fournit pas.
Utiliser les enums avec Symfony et Doctrine
Le support des Symfony enum s’est considérablement amélioré depuis Symfony 6.1. Les enums PHP sont désormais des citoyens de première classe dans l’écosystème Symfony.
Formulaires Symfony
use Symfony\Component\Form\Extension\Core\Type\EnumType;
$builder->add('statut', EnumType::class, [
'class' => Statut::class,
'choice_label' => fn(Statut $s) => $s->label(),
]);
Le type EnumType génère automatiquement les options du champ à partir des cas de l’énumération. Plus besoin de maintenir manuellement la liste des choix.
Doctrine ORM
Depuis Doctrine ORM 2.11, les enums sont supportés nativement comme type de colonne :
use Doctrine\ORM\Mapping as ORM;
#[ORM\Entity]
class Article {
#[ORM\Column(type: 'string', enumType: Statut::class)]
private Statut $statut;
public function getStatut(): Statut {
return $this->statut;
}
public function setStatut(Statut $statut): void {
$this->statut = $statut;
}
}
Doctrine se charge automatiquement de convertir entre la valeur scalaire en base et l’instance d’enum en PHP. Lors de la lecture, il appelle Statut::from() sur la valeur stockée. Lors de l’écriture, il persiste $statut->value.
Validation et sérialisation API
Avec le composant Serializer de Symfony, les Backed Enums sont automatiquement sérialisés en leur valeur scalaire et désérialisés vers le cas correspondant. Pour la validation, Symfony propose la contrainte Choice compatible avec les enums, mais le typage strict rend souvent cette contrainte superflue.
Bonnes pratiques et pièges à éviter
Après plusieurs années d’utilisation des enums en production, voici les recommandations que je partage systématiquement avec mes étudiants et mes équipes.
Privilégiez les Backed Enums
Sauf cas très spécifique, optez toujours pour un Backed Enum avec des valeurs string. Les valeurs int sont tentantes pour l’optimisation, mais elles perdent en lisibilité quand vous inspectez la base de données. Un champ contenant "publie" est immédiatement compréhensible ; un champ contenant 2 ne l’est pas.
Nommez les cas en PascalCase
La convention PHP-FIG et la documentation officielle utilisent le PascalCase pour les noms de cas : Statut::EnCours plutôt que Statut::EN_COURS ou Statut::enCours. Respectez cette convention pour rester cohérent avec l’écosystème.
Ne mettez pas de logique métier complexe dans les enums
Les méthodes dans les enums doivent rester courtes et orientées présentation : label, icône, couleur CSS, format d’affichage. Si vous commencez à y injecter des dépendances ou de la logique métier lourde, c’est le signe qu’un service dédié serait plus approprié.
Attention à la sérialisation JSON
Par défaut, json_encode() sur un Backed Enum retourne la valeur scalaire. Sur un Pure Enum, le résultat est moins prévisible. Si vous construisez une API, assurez-vous de contrôler explicitement la sérialisation, par exemple en implémentant JsonSerializable :
enum Statut: string implements \JsonSerializable {
case Brouillon = 'brouillon';
case Publie = 'publie';
case Archive = 'archive';
public function jsonSerialize(): string {
return $this->value;
}
}
Les enums ne sont pas extensibles
Contrairement aux classes, un enum ne peut pas être étendu via l’héritage. C’est un choix de conception délibéré : un ensemble fini de valeurs ne doit pas être élargi de façon incontrôlée par des sous-types. Si vous avez besoin de hiérarchies de types, combinez interfaces et plusieurs enums distincts.
Migration depuis les anciennes approches
Si votre projet utilise encore des classes avec constantes ou des bibliothèques comme myclabs/php-enum, la migration vers les enums natifs est relativement simple. Remplacez la classe par un enum, ses constantes par des cas, et mettez à jour les type-hints. Les comparaisons === continuent de fonctionner, mais vous devrez adapter les éventuelles vérifications instanceof. La page officielle des nouveautés PHP 8.1 détaille toutes les modifications de comportement à anticiper.
À retenir
- Utilisez PHP 8.1 minimum pour accéder aux enums natifs ; ciblez PHP 8.2+ en production
- Préférez les Backed Enums avec des valeurs string pour une meilleure lisibilité en base de données
- Utilisez tryFrom() plutôt que from() pour les données provenant de l’extérieur
- Combinez enums et expression match pour un code exhaustif et sûr
- Gardez les méthodes d’enum courtes et orientées présentation ; déplacez la logique métier dans des services
Questions fréquentes
Quelle version de PHP utilise enum ?
Les énumérations (enum) sont disponibles à partir de PHP 8.1, sorti en novembre 2021. Toute version antérieure ne supporte pas cette fonctionnalité nativement. En 2026, je recommande de cibler PHP 8.2 ou 8.3 pour bénéficier des dernières corrections et optimisations liées aux enums.
Un enum (énumération) est un type de données qui restreint une variable à un ensemble fini de valeurs nommées, déclarées à l’avance. Par exemple, un enum Statut peut ne contenir que les cas Brouillon, Publié et Archivé. Contrairement à une simple constante string ou int, le typage enum empêche toute valeur non prévue d’être utilisée.C’est quoi le type enum en PHP ?
Utilisez le mot-clé Comment définir une énumération en PHP ?
enum suivi du nom, éventuellement d’un type de base (: string ou : int), puis listez les cas avec le mot-clé case. Exemple : enum Role: string { case Admin = 'admin'; case User = 'user'; }. L’enum se place dans son propre fichier, comme une classe.
Déclarez votre enum, puis utilisez-le comme type-hint dans vos fonctions, propriétés de classe ou paramètres de méthode. Pour convertir une valeur issue d’un formulaire ou d’une API, appelez Comment utiliser enum dans un projet concret ?
MonEnum::tryFrom($valeur). Pour lister tous les cas possibles dans un select HTML, utilisez MonEnum::cases(). Avec Doctrine, déclarez le type de colonne avec l’attribut enumType pour un mapping automatique.
Un enum est un type fermé avec un nombre fixe de cas ; il ne peut pas être instancié librement ni étendu par héritage. Une classe est un type ouvert : elle peut être instanciée, posséder des propriétés d’instance et être héritée. Les enums supportent les méthodes et les interfaces, mais pas les propriétés d’instance ni l’héritage.Quelle est la différence entre enum et class en PHP ?
Oui. Depuis Symfony 6.1, le type de formulaire Peut-on utiliser les enums avec Symfony et Doctrine ?
EnumType gère nativement les enums PHP. Doctrine ORM 2.11 et supérieur supporte l’attribut enumType sur les colonnes, ce qui permet un mapping automatique entre la valeur en base de données et l’instance d’enum en PHP. Le Serializer Symfony sérialise et désérialise les Backed Enums sans configuration supplémentaire.
La méthode la plus simple est d’utiliser Comment vérifier si une valeur existe dans un enum PHP ?
tryFrom() : si elle retourne null, la valeur n’existe pas dans l’enum. Exemple : if (Statut::tryFrom('maValeur') !== null) { /* valide */ }. Vous pouvez aussi itérer sur Statut::cases() pour comparer les valeurs manuellement.
Formatrice IT indépendante depuis 2016, ancienne étudiante BTS SIO SLAM. 6 ans d'expérience en entreprise.