Die Verwendung dieser Bibliothek wird insbesondere für neue Projekte nicht mehr empfohlen. PHP 8.1 unterstützt Aufzählungen nativ.
Siehe #332.
Einfache, erweiterbare und leistungsstarke Aufzählungsimplementierung für Laravel.
Enum-Schlüsselwertpaare als Klassenkonstanten
Umfassendes Methodenpaket
Enum-Instanziierung
Markierte/bitweise Aufzählungen
Geben Sie Hinweise ein
Attributumwandlung
Enum-Handwerker-Generator
Validierungsregeln für die Übergabe von Enumerationsschlüsseln oder -werten als Eingabeparameter
Lokalisierungsunterstützung
Erweiterbar über Makros
Erstellt von Ben Sampson
Führung
Installation
Migrieren Sie zu nativen PHP-Enums
Enum-Bibliothek
Grundlegende Verwendung
Enum-Definition
Instanziierung
Instanzeigenschaften
Instanz-Casting
Instanzgleichheit
Geben Sie Hinweise ein
Markierte/bitweise Aufzählung
Attribut-Casting
Migrationen
Validierung
Lokalisierung
Anpassen von Beschreibungen
Anpassen der Klassenbeschreibung
Anpassen von Wertbeschreibungen
Erweitern der Enum-Basisklasse
Laravel Nova-Integration
PHPStan-Integration
Handwerker-Befehlsliste
Enum-Klassenreferenz
Stubs
Sie lesen die Dokumentation für 6.x
Wenn Sie Laravel 8 verwenden, lesen Sie bitte die Dokumentation für 4.x
Wenn Sie Laravel 7 verwenden, lesen Sie bitte die Dokumentation für 2.x
Wenn Sie Laravel 6 oder niedriger verwenden, lesen Sie bitte die Dokumentation für 1.x
Informationen zum Upgrade auf die neueste Version finden Sie im Upgrade-Leitfaden.
Ich habe einen Blogbeitrag über die Verwendung von laravel-enum geschrieben: https://sampo.co.uk/blog/using-enums-in-laravel
Erfordert PHP 8 und Laravel 9 oder 10.
Komponist benötigt Bensampo/Laravel-Enum
PHP 8.1 unterstützt Aufzählungen nativ. Mit den folgenden Schritten können Sie Ihre Verwendung von BenSampoEnumEnum
auf native PHP-Enums migrieren.
Stellen Sie sicher, dass Sie die folgenden Anforderungen erfüllen:
PHP 8.1 oder höher
Laravel 10 oder höher
Rector 0.17 oder höher, Ihre rector.php
enthält alle relevanten Dateien
Neueste Version dieser Bibliothek
Abhängig von der Größe Ihres Projekts können Sie alle Aufzählungen auf einmal migrieren oder jeweils nur ein paar oder eine Aufzählung migrieren.
Konvertieren Sie alle Enumerationen auf einmal: php artisan enum:to-native
Übergeben Sie den vollständig qualifizierten Klassennamen einer Aufzählung, um die Konvertierung einzuschränken: php artisan enum:to-native "AppEnumsUserType"
Dies ist erforderlich, wenn während der Bootstrap-Phase von Laravel Aufzählungen verwendet werden. Die Konvertierung ihrer Verwendungen beeinträchtigt Larastan und verhindert, dass ein zweiter Lauf von Rector funktioniert.
Überprüfen und validieren Sie die Codeänderungen auf fehlende Randfälle:
Siehe Nicht implementiert
Enum::coerce()
: Wenn nur Werte übergeben wurden, können Sie diese durch tryFrom()
ersetzen. Wenn auch Schlüssel oder Instanzen übergeben werden könnten, benötigen Sie möglicherweise zusätzliche Logik, um dies abzudecken.
Enum::$description
und Enum::getDescription()
: Implementieren Sie eine Alternative.
try/catch-Blöcke, die BenSampoEnumExceptionsInvalidEnumKeyException
oder BenSampoEnumExceptionsInvalidEnumMemberException
behandeln. Fangen Sie entweder den von nativen Aufzählungen ausgelösten ValueError
ab oder wechseln Sie zur Verwendung von tryFrom()
und behandeln Sie null
.
Sobald alle Aufzählungen konvertiert sind, können Sie Ihre Abhängigkeit von dieser Bibliothek entfernen.
Durchsuchen und laden Sie eine Liste häufig verwendeter, von der Community bereitgestellter Aufzählungen herunter.
Enum-Bibliothek →
Sie können den folgenden Artisan-Befehl verwenden, um eine neue Enum-Klasse zu generieren:
php artisan make:enum UserType
Jetzt müssen Sie nur noch die möglichen Werte hinzufügen, die Ihre Aufzählung als Konstanten haben kann.
<?php define(strict_types=1);namespace AppEnums;use BenSampoEnumEnum;final class UserType erweitert Enum {const Administrator = 0;const Moderator = 1;const Subscriber = 2;const SuperAdministrator = 3; }
Das ist es! Beachten Sie, dass Sie auf die Enum-Werte einfach wie auf jede andere Klassenkonstante zugreifen können, da sie als einfache Konstanten definiert sind.
UserType::Administrator // Hat den Wert 0
Es kann nützlich sein, Aufzählungen zu instanziieren, um sie mithilfe der Typangabe zwischen Funktionen zu übergeben.
Darüber hinaus ist es unmöglich, eine Enumeration mit einem ungültigen Wert zu instanziieren, sodass Sie sicher sein können, dass der übergebene Wert immer gültig ist.
Der Einfachheit halber können Aufzählungen auf verschiedene Arten instanziiert werden:
// Neue Standard-PHP-Klasse, die den gewünschten Enum-Wert als Parameter übergibt$enumInstance = new UserType(UserType::Administrator);// Gleich wie der Konstruktor, instanziiert nach Wert$enumInstance = UserType::fromValue(UserType::Administrator) ;// Einen Enum-Schlüssel anstelle seines Werts verwenden$enumInstance = UserType::fromKey('Administrator');// Statischer Aufruf des Schlüsselnamens als Methode unter Verwendung von __callStatic magic$enumInstance = UserType::Administrator();// Versuch, eine neue Enum mit dem angegebenen Schlüssel oder Wert zu instanziieren. Gibt null zurück, wenn die Aufzählung nicht instanziiert werden kann.$enumInstance = UserType::coerce($someValue);
Wenn Sie möchten, dass Ihre IDE die statischen Instanziierungshilfsprogramme automatisch vervollständigt, können Sie PHPDoc-Anmerkungen über einen handwerklichen Befehl generieren.
Standardmäßig werden alle Enums in app/Enums
mit Anmerkungen versehen (Sie können den Ordner ändern, indem Sie einen Pfad an --folder
übergeben).
php artisan enum:annotate
Sie können eine einzelne Klasse mit Anmerkungen versehen, indem Sie den Klassennamen angeben.
php artisan enum:annotate „AppEnumsUserType“
Sobald Sie über eine Enum-Instanz verfügen, können Sie als Eigenschaften auf den key
, value
und description
zugreifen.
$userType = UserType::fromValue(UserType::SuperAdministrator);$userType->key; // SuperAdministrator$userType->value; // 3$userType->description; // Superadministrator
Dies ist besonders nützlich, wenn Sie eine Enum-Instanz an eine Blade-Ansicht übergeben.
Enum-Instanzen können in Strings umgewandelt werden, wenn sie die magische Methode __toString()
implementieren.
Dies bedeutet auch, dass sie beispielsweise in Blade-Ansichten wiedergegeben werden können.
$userType = UserType::fromValue(UserType::SuperAdministrator); (string) $userType // '3'
Sie können die Gleichheit einer Instanz anhand eines beliebigen Werts überprüfen, indem Sie ihn an die Methode is
übergeben. Der Einfachheit halber gibt es auch eine isNot
-Methode, die genau das Gegenteil der is
-Methode ist.
$admin = UserType::Administrator();$admin->is(UserType::Administrator); // true$admin->is($admin); // true$admin->is(UserType::Administrator()); // true$admin->is(UserType::Moderator); // false$admin->is(UserType::Moderator()); // false$admin->is('random-value'); // FALSCH
Sie können auch mithilfe der in
Methode prüfen, ob der Wert der Instanz mit einem Array möglicher Werte übereinstimmt, und mit notIn
prüfen, ob sich der Instanzwert nicht in einem Array von Werten befindet. Iterables können auch gegengeprüft werden.
$admin = UserType::Administrator();$admin->in([UserType::Moderator, UserType::Administrator]); // true$admin->in([UserType::Moderator(), UserType::Administrator()]); // true$admin->in([UserType::Moderator, UserType::Subscriber]); // false$admin->in(['random-value']); // false$admin->notIn([UserType::Moderator, UserType::Administrator]); // false$admin->notIn([UserType::Moderator(), UserType::Administrator()]); // false$admin->notIn([UserType::Moderator, UserType::Subscriber]); // true$admin->notIn(['random-value']); // WAHR
Die instanziierten Aufzählungen sind keine Singletons, sondern es wird jedes Mal ein neues Objekt erstellt. Daher wird ein strenger Vergleich ===
verschiedener Enum-Instanzen unabhängig vom Wert immer false
zurückgeben. Im Gegensatz dazu hängt ein loser Vergleich ==
vom Wert ab.
$admin = UserType::Administrator();$admin === UserType::Administrator(); // falseUserType::Administrator() === UserType::Administrator(); // false$admin === UserType::Moderator(); // false$admin === $admin; // true$admin == UserType::Administrator(); // true$admin == UserType::Administrator; // true$admin == UserType::Moderator(); // false$admin == UserType::Moderator; // FALSCH
Einer der Vorteile von Enum-Instanzen besteht darin, dass Sie damit Typhinweise verwenden können, wie unten gezeigt.
Funktion canPerformAction(UserType $userType) {if ($userType->is(UserType::SuperAdministrator)) {return true; }return false; }$userType1 = UserType::fromValue(UserType::SuperAdministrator);$userType2 = UserType::fromValue(UserType::Moderator);canPerformAction($userType1); // Gibt truecanPerformAction($userType2) zurück; // Gibt false zurück
Standard-Enumerationen stellen jeweils einen einzelnen Wert dar, markierte oder bitweise Enumerationen können jedoch mehrere Werte gleichzeitig darstellen. Dies macht sie perfekt, wenn Sie mehrere Auswahlmöglichkeiten aus einer begrenzten Auswahl an Optionen ausdrücken möchten. Ein gutes Beispiel hierfür wären Benutzerberechtigungen, bei denen es eine begrenzte Anzahl möglicher Berechtigungen gibt, ein Benutzer jedoch keine, einige oder alle davon haben kann.
Mit dem folgenden handwerklichen Befehl können Sie eine markierte Aufzählung erstellen:
php artisan make:enum UserPermissions --flagged
Beim Definieren von Werten müssen Sie Potenzen von 2 verwenden. Der einfachste Weg, dies zu tun, ist die Verwendung des Linksverschiebungsoperators <<
wie folgt:
Die letzte Klasse UserPermissions erweitert FlaggedEnum {const ReadComments = 1 << 0;const WriteComments = 1 << 1;const EditComments = 1 << 2;const DeleteComments = 1 << 3;// Das nächste wäre „1 << 4“ und so weiter. ..}
Sie können bitweise oder |
verwenden um einen Verknüpfungswert festzulegen, der einen bestimmten Satz von Werten darstellt.
Die letzte Klasse UserPermissions erweitert FlaggedEnum {const ReadComments = 1 << 0;const WriteComments = 1 << 1;const EditComments = 1 << 2;const DeleteComments = 1 << 3;// Shortcutsconst Member = self::ReadComments | self::WriteComments; // Lesen und schreiben.const Moderator = self::Member | self::EditComments; // Alle Berechtigungen, die ein Mitglied hat, plus Edit.const Admin = self::Moderator | self::DeleteComments; // Alle Berechtigungen, die ein Moderator hat, plus Löschen.}
Es gibt mehrere Möglichkeiten, eine markierte Enumeration zu instanziieren:
// Neue Standard-PHP-Klasse, die die gewünschten Enum-Werte als Array von Werten oder Array von Enum-Instanzen übergibt$permissions = new UserPermissions([UserPermissions::ReadComments, UserPermissions::EditComments]);$permissions = new UserPermissions([UserPermissions: :ReadComments(), UserPermissions::EditComments()]);// Statische Flags-Methode, die wiederum die gewünschten Enum-Werte als Array von Werten oder Array übergibt von Enum-Instanzen$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::EditComments]);$permissions = UserPermissions::flags([UserPermissions::ReadComments(), UserPermissions::EditComments()]);
Die Attributumwandlung funktioniert auf die gleiche Weise wie die Aufzählung einzelner Werte.
Gekennzeichnete Aufzählungen dürfen überhaupt keinen Wert enthalten. Jede markierte Enumeration hat die vordefinierte Konstante None
, die mit 0
vergleichbar ist.
UserPermissions::flags([])->value === UserPermissions::None; // WAHR
Zusätzlich zu den standardmäßigen Aufzählungsmethoden stehen für gekennzeichnete Aufzählungen eine Reihe hilfreicher Methoden zur Verfügung.
Hinweis: Überall dort, wo eine statische Eigenschaft übergeben wird, können Sie auch eine Enum-Instanz übergeben.
Setzen Sie die Flags für die Aufzählung auf das angegebene Flag-Array.
$permissions = UserPermissions::flags([UserPermissions::ReadComments]);$permissions->flags([UserPermissions::EditComments, UserPermissions::DeleteComments]); // Flags sind jetzt: EditComments, DeleteComments.
Fügen Sie das angegebene Flag zur Enumeration hinzu
$permissions = UserPermissions::flags([UserPermissions::ReadComments]);$permissions->addFlag(UserPermissions::EditComments); // Flags sind jetzt: ReadComments, EditComments.
Fügen Sie die angegebenen Flags zur Enumeration hinzu
$permissions = UserPermissions::flags([UserPermissions::ReadComments]);$permissions->addFlags([UserPermissions::EditComments, UserPermissions::WriteComments]); // Flags sind jetzt: ReadComments, EditComments, WriteComments.
Fügen Sie alle Flags zur Enumeration hinzu
$permissions = UserPermissions::flags([UserPermissions::ReadComments]);$permissions->addAllFlags(); // Enum hat jetzt alle Flags
Entfernen Sie das angegebene Flag aus der Enumeration
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->removeFlag(UserPermissions::ReadComments); // Flags sind jetzt: WriteComments.
Entfernen Sie die angegebenen Flags aus der Enumeration
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments, UserPermissions::EditComments]);$permissions->removeFlags([UserPermissions::ReadComments, UserPermissions::WriteComments]); // Flags sind jetzt: EditComments.
Entfernen Sie alle Flags aus der Enumeration
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->removeAllFlags();
Überprüfen Sie, ob die Enumeration das angegebene Flag hat.
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->hasFlag(UserPermissions::ReadComments); // True$permissions->hasFlag(UserPermissions::EditComments); // FALSCH
Überprüfen Sie, ob die Enumeration alle angegebenen Flags enthält.
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->hasFlags([UserPermissions::ReadComments, UserPermissions::WriteComments]); // True$permissions->hasFlags([UserPermissions::ReadComments, UserPermissions::EditComments]); // FALSCH
Überprüfen Sie, ob die Enumeration nicht über das angegebene Flag verfügt.
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->notHasFlag(UserPermissions::EditComments); // True$permissions->notHasFlag(UserPermissions::ReadComments); // FALSCH
Überprüfen Sie, ob die Enumeration keines der angegebenen Flags enthält.
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->notHasFlags([UserPermissions::ReadComments, UserPermissions::EditComments]); // True$permissions->notHasFlags([UserPermissions::ReadComments, UserPermissions::WriteComments]); // FALSCH
Gibt die Flags als Array von Instanzen zurück.
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->getFlags(); // [UserPermissions::ReadComments(), UserPermissions::WriteComments()];
Überprüfen Sie, ob in der Enumeration mehrere Flags gesetzt sind.
$permissions = UserPermissions::flags([UserPermissions::ReadComments, UserPermissions::WriteComments]);$permissions->hasMultipleFlags(); // True;$permissions->removeFlag(UserPermissions::ReadComments)->hasMultipleFlags(); // FALSCH
Rufen Sie die Bitmaske für die Enumeration ab.
UserPermissions::Member()->getBitmask(); // 11;UserPermissions::Moderator()->getBitmask(); // 111;UserPermissions::Admin()->getBitmask(); // 1111;UserPermissions::DeleteComments()->getBitmask(); // 1000;
Um gekennzeichnete Aufzählungen direkt in Ihren Eloquent-Abfragen zu verwenden, können Sie die Eigenschaft QueriesFlaggedEnums
in Ihrem Modell verwenden, die Ihnen die folgenden Methoden bietet:
User::hasFlag('permissions', UserPermissions::DeleteComments())->get();
User::notHasFlag('permissions', UserPermissions::DeleteComments())->get();
User::hasAllFlags('permissions', [UserPermissions::EditComment(), UserPermissions::ReadComment()])->get();
User::hasAnyFlags('permissions', [UserPermissions::DeleteComments(), UserPermissions::EditComments()])->get();
Sie können Modellattribute mithilfe der integrierten benutzerdefinierten Umwandlung von Laravel in Aufzählungen umwandeln. Dadurch wird das Attribut beim Abrufen in eine Enum-Instanz umgewandelt und beim Festlegen wieder auf den Enum-Wert zurückgesetzt. Da Enum::class
den Castable
-Vertrag implementiert, müssen Sie nur den Klassennamen der Aufzählung angeben:
use BenSampoEnumTestsEnumsUserType;use IlluminateDatabaseEloquentModel;class Beispiel erweitert Model {protected $casts = ['random_flag' => 'boolean', // Beispiel für Standard-Laravel-Cast'user_type' => UserType::class, // Beispiel für Enum-Cast]; }
Wenn Sie nun auf das user_type
Attribut Ihres Example
zugreifen, wird der zugrunde liegende Wert als UserType
Enumeration zurückgegeben.
$example = Beispiel::first();$example->user_type // Instanz von UserType
Sehen Sie sich die für Enum-Instanzen verfügbaren Methoden und Eigenschaften an, um die Attributumwandlung optimal zu nutzen.
Sie können den Wert festlegen, indem Sie entweder den Enum-Wert oder eine andere Enum-Instanz übergeben.
$example = Beispiel::first();// Mit Aufzählungswert festlegen$example->user_type = UserType::Moderator;// Mit Aufzählung festlegen Instanz$example->user_type = UserType::Moderator();
$model->toArray()
Wenn Sie toArray
verwenden (oder Modelle von Ihrem Controller als Antwort zurückgeben), ruft Laravel die toArray
Methode für die Enum-Instanz auf.
Standardmäßig wird dadurch nur der Wert in seinem nativen Typ zurückgegeben. Möglicherweise möchten Sie auch Zugriff auf die anderen Eigenschaften (Schlüssel, Beschreibung) haben, um beispielsweise zur Javascript-App zurückzukehren.
Um dieses Verhalten anzupassen, können Sie die toArray
-Methode auf der Enum-Instanz überschreiben.
// Beispiel für die Enumfinal-Klasse UserType erweitert Enum {const ADMINISTRATOR = 0;const MODERATOR = 1; }$instance = UserType::Moderator();// Defaultpublic function toArray() {return $this->value; }// Gibt int(1) zurück// Gibt alle Eigenschaften zurückpublic function toArray() {return $this; }// Gibt ein Array aller Eigenschaften zurück// array(3) {// ["value"]=>// int(1)"// ["key"]=>// string(9) "MODERATOR "// ["description"]=>// string(9) "Moderator"// }
Viele Datenbanken geben alles als Zeichenfolgen zurück (z. B. kann eine Ganzzahl als Zeichenfolge '1'
zurückgegeben werden). Um die Reibung für Benutzer der Bibliothek zu verringern, verwenden wir Typzwang, um den beabsichtigten Wert herauszufinden. Wenn Sie dies lieber steuern möchten, können Sie die statische Methode parseDatabase
in Ihrer Enum-Klasse überschreiben:
Die letzte Klasse UserType erweitert Enum {const Administrator = 0;const Moderator = 1;public static function parseDatabase($value) {return (int) $value; } }
Die Rückgabe von null
von der parseDatabase
-Methode führt dazu, dass das Attribut im Modell ebenfalls null
ist. Dies kann nützlich sein, wenn Ihre Datenbank inkonsistente Leerwerte wie leere Zeichenfolgen anstelle von NULL
speichert.
Wenn Sie Attribute Ihres Modells in Aufzählungen umwandeln, kann das Paket laravel-ide-helper verwendet werden, um automatisch Eigenschaftsdokumentblöcke für Sie zu generieren.
Da Aufzählungen die Konsistenz auf Codeebene erzwingen, ist es nicht erforderlich, dies auf Datenbankebene erneut zu tun. Daher ist der empfohlene Typ für Datenbankspalten abhängig von Ihren Aufzählungswerten string
oder int
. Das bedeutet, dass Sie Enum-Werte in Ihrem Code hinzufügen/entfernen können, ohne sich Gedanken über Ihre Datenbankschicht machen zu müssen.
AppEnumsUserType verwenden; IlluminateSupportFacadesSchema verwenden; IlluminateDatabaseSchemaBlueprint verwenden; IlluminateDatabaseMigrationsMigration verwenden; Klasse CreateUsersTable erweitert Migration {/** * Führen Sie die Migrationen aus. * * @return void */public function up(): void{ Schema::table('users', function (Blueprint $table): void {$table->bigIncrements('id');$table->timestamps();$table->string('type') ->default(UserType::Moderator); }); } }
enum
Spaltentyps Alternativ können Sie in Ihren Migrationen Enum
-Klassen verwenden, um Enum-Spalten zu definieren. Die Enum-Werte müssen als Strings definiert werden.
AppEnumsUserType verwenden; IlluminateSupportFacadesSchema verwenden; IlluminateDatabaseSchemaBlueprint verwenden; IlluminateDatabaseMigrationsMigration verwenden; Klasse CreateUsersTable erweitert Migration {/** * Führen Sie die Migrationen aus. * * @return void */public function up(): void{ Schema::table('users', function (Blueprint $table): void {$table->bigIncrements('id');$table->timestamps();$table->enum('type', UserType:: getValues()) ->default(UserType::Moderator); }); } }
Mithilfe der EnumValue
-Regel können Sie überprüfen, ob ein an einen Controller übergebener Enumerationswert ein gültiger Wert für eine bestimmte Enumeration ist.
use BenSampoEnumRulesEnumValue;public function store(Request $request) {$this->validate($request, ['user_type' => ['required', new EnumValue(UserType::class)], ]); }
Standardmäßig ist die Typprüfung auf „strikt“ eingestellt. Sie können dies jedoch umgehen, indem Sie false
an den optionalen zweiten Parameter der EnumValue-Klasse übergeben.
new EnumValue(UserType::class, false) // Strikte Typprüfung ausschalten.
Sie können Schlüssel auch mithilfe der EnumKey
-Regel validieren. Dies ist nützlich, wenn Sie den Enumerationsschlüssel beispielsweise als URL-Parameter zum Sortieren oder Filtern verwenden.
use BenSampoEnumRulesEnumKey;public function store(Request $request) {$this->validate($request, ['user_type' => ['required', new <span class="pl-v"