Maison  >  Article  >  développement back-end  >  Explication des nouvelles fonctionnalités de PHP8.1 Énumération Enums

Explication des nouvelles fonctionnalités de PHP8.1 Énumération Enums

藏色散人
藏色散人original
2021-11-10 15:09:314897parcourir

Cet article est traduit, adresse originale : https://stitcher.io/blog/php-enums

PHP 8.1 : Énumérations

Ils sont enfin là - le support intégré pour les énumérations sera ajouté en PHP Prise en charge de la version 8.1 ! Certains pensent peut-être qu'ils auraient dû le faire il y a longtemps, mais vous n'avez pas entendu ma plainte ; je suis content qu'ils l'aient fait ! Cet article est consacré à une analyse approfondie des fonctionnalités nouvellement ajoutées.

Comme d'habitude dans mes articles sur les fonctionnalités PHP, nous commençons par un aperçu de haut niveau de ce à quoi ressemblent les énumérations :

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
}

La bonne chose à propos des énumérations est qu'elles représentent un ensemble de valeurs constantes, mais surtout ces valeurs peuvent be Tapez-le comme ceci :

class BlogPost
{
    public function __construct(
        public Status $status, 
    ) {}
}

Dans cet exemple, créer une énumération et la transmettre à aBlogPost ressemble à ceci :

$post = new BlogPost(Status::DRAFT);

Voilà pour les bases, et comme vous pouvez le voir, ce n'est pas compliqué du tout. Bien qu’il y ait beaucoup de notes annexes à prendre, examinons de plus près les énumérations !

#Méthodes d'énumération

Les énumérations peuvent définir des méthodes, tout comme les classes. C'est une fonctionnalité très puissante, surtout lorsqu'elle est combinée avec l'opérateur de correspondance :

enum Status
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
    
    public function color(): string
    {
        return match($this) 
        {
            Status::DRAFT => 'grey',   
            Status::PUBLISHED => 'green',   
            Status::ARCHIVED => 'red',   
        };
    }
}

Les méthodes peuvent être utilisées comme ceci :

$status = Status::ARCHIVED;
$status->color(); // 'red'

Les méthodes statiques sont également autorisées :

enum Status
{
    // …
    
    public static function make(): Status
    {
        // …
    }
}

Vous pouvez également utiliser self dans une énumération :

enum Status
{
    // …
    
    public function color(): string
    {
        return match($this) 
        {
            self::DRAFT => 'grey',   
            self::PUBLISHED => 'green',   
            self::ARCHIVED => 'red',   
        };
    }
}

# Interface d'énumération

Les énumérations peuvent implémenter des interfaces, tout comme les classes normales :

interface HasColor
{
    public function color(): string;
}
enum Status implements HasColor
{
    case DRAFT;
    case PUBLISHED;
    case ARCHIVED;
    
    public function color(): string { /* … */ }
}

# Valeurs d'énumération - alias "énumérations prises en charge"

Les valeurs d'énumération sont représentées en interne par des objets, mais vous pouvez attribuer des valeurs ​​à eux selon les besoins ; cela est utile par ex. Sérialisez-les dans la base de données.

enum Status: string
{
    case DRAFT = 'draft';
    case PUBLISHED = 'published';
    case ARCHIVED = 'archived';
}

Faites attention à la déclaration de type dans la définition de l'énumération. Il indique que toutes les valeurs d'énumération appartiennent au type donné. Vous pouvez également en faire un int. Notez que seuls les valeurs int et string sont autorisées comme valeurs d'énumération.

enum Status: int
{
    case DRAFT = 1;
    case PUBLISHED = 2;
    case ARCHIVED = 3;
}

Le terme technique pour les énumérations de types est appelé « énumérations sauvegardées » car elles sont « soutenues » par des valeurs plus simples. Si vous décidez d'attribuer une valeur d'énumération, tous les cas doivent avoir une valeur. Vous ne pouvez pas les mélanger et les assortir. Les énumérations sans « sauvegarde » sont appelées « énumérations pures ».

#Énumérations prises en charge avec interfaces

Si vous utilisez une énumération prise en charge avec une interface, le type d'énumération doit apparaître directement après le nom de l'énumération et avant le mot-clé Implements.

enum Status: string implements HasColor
{
    case DRAFT = 'draft';
    case PUBLISHED = 'published';
    case ARCHIVED = 'archived';
    
    // …
}

#Énumérations prises en charge par la sérialisation

Si vous souhaitez attribuer des valeurs aux cas d'énumération, vous aurez peut-être besoin d'un moyen de les sérialiser et de les désérialiser. Les sérialiser signifie que vous avez besoin d'un moyen d'accéder aux valeurs enum. Cela se fait via une propriété publique en lecture seule :

$value = Status::PUBLISHED->value; // 2

L'énumération peut être restaurée à partir de la valeur en utilisant : Enum::from

$status = Status::from(2); // Status::PUBLISHED

Il existe également un tryFrom qui renvoie null si une valeur inconnue est passée. Il existe une exception si vous utilisez from.

$status = Status::from('unknown'); // ValueError
$status = Status::tryFrom('unknown'); // null

Veuillez noter que vous pouvez également utiliser les fonctions intégrées de sérialisation et de désérialisation sur les énumérations. De plus, vous pouvez utiliser json_encode avec une énumération prise en charge et le résultat sera une valeur d'énumération. Ce comportement peut être remplacé en implémentant JsonSeriallessly.

#Liste des valeurs d'énumération

Vous pouvez obtenir une liste de tous les cas disponibles dans une énumération en utilisant la méthode statique : Enum::cases()

Status::cases();
/* [
    Status::DRAFT, 
    Status::PUBLISHED, 
    Status::ARCHIVED
] */

Notez que ce tableau contient l'objet d'énumération réel :

array_map(
    fn(Status $status) => $status->color(), 
    Status::cases()
);

#Les énumérations sont des objets

J'ai déjà mentionné que les valeurs d'énumération sont représentées comme des objets, en fait ce sont des objets singleton. Cela signifie que vous pouvez les comparer comme ceci :

$statusA = Status::PENDING;
$statusB = Status::PENDING;
$statusC = Status::ARCHIVED;
$statusA === $statusB; // true
$statusA === $statusC; // false
$statusC instanceof Status; // true

#Enums comme clés de tableau

Puisque les valeurs d'énumération sont en fait des objets, vous ne pouvez actuellement pas les utiliser comme clés de tableau. Ce qui suit entraînera une erreur :

$list = [
    Status::DRAFT => 'draft',
    // …
];

Il existe une RFC pour modifier ce comportement, mais elle n'a pas encore été votée.

Cela signifie que vous ne pouvez utiliser que des énumérations comme clés dans SplObjectStorage et WeakMaps.

#Traits

Les énumérations peuvent utiliser des traits comme les classes, mais avec plus de restrictions. Le remplacement des méthodes d'énumération intégrées n'est pas autorisé et elles ne peuvent pas contenir d'attributs de classe - leur utilisation dans les énumérations est interdite.

#Réflexion et Propriétés

Comme prévu, certaines classes de réflexion ont été ajoutées pour gérer les énumérations : ReflectionEnum, ReflectionEnumUnitCase et ReflectionEnumBackedCase. Il existe également une nouvelle fonction enum_exists, qui fait exactement ce que son nom suggère.

Tout comme les classes et attributs normaux, les énumérations et leurs cas peuvent être annotés à l'aide d'attributs. Notez que le filtre TARGET_CLASS inclura également les énumérations.

Une dernière chose : l'énumération a également une propriété en lecture seule, la RFC mentionne qu'il s'agit d'un détail d'implémentation et ne doit être utilisée qu'à des fins de débogage. Mais cela mérite quand même d’être mentionné. $enum->name

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn