BackedEnum - Przegląd PHP #3
Historia pewnego developera, który postanowił pożegnać się z niekończącymi się const
i tablicami mapperów.
Przy okazji dowiesz się, czym są BackedEnums
, jakie mają plusy i minusy, i czemu czasem lepiej sięgnąć po enum-name
niż powielać wartości stringów.
🤔 Co to w ogóle są te BackedEnums?
Od PHP 8.1 dostaliśmy wreszcie coś, na co czekaliśmy od lat – enumy!
A do tego mamy ich bardziej wypasioną wersję – BackedEnums.
Są to takie enumy, które oprócz nazwy mogą mieć jeszcze wartość (string
albo int
).
Brzmi jak const
w klasie, ale jest o niebo lepsze. 💪
Przykład w akcji
enum Status: string {
case NEW = 'new';
case IN_PROGRESS = 'in_progress';
case DONE = 'done';
}
// Użycie
$orderStatus = Status::NEW;
echo $orderStatus-value; // "new"
echo $orderStatus-name; // "NEW"
🧐 A po co mi to?
Zalety:
- ✅ Czytelność – koniec z magicznymi stringami i zgadywaniem, co autor miał na myśli.
- ✅ Bezpieczeństwo typów – nie wciśniesz do funkcji
"N3W"
zamiast"NEW"
. - ✅ Łatwość refaktoryzacji – zmieniasz wartość w jednym miejscu i gotowe.
- ✅ Metody pomocnicze – możesz wrzucać do enumów logikę (np.
isFinished()
).
Wady:
- ❌ Tylko w PHP 8.1+ – jeśli utknąłeś na 7.4, to pozostaje ci tylko płakać w kącie.
- ❌ Trochę magii – przy dużych projektach musisz dobrze przemyśleć, czy używać
value
czyname
. - ❌ Overkill dla prostych przypadków – jak masz 2 wartości na krzyż, to może wystarczyć
const
.
😅 Dlaczego BackedEnums
dla stringów mogą być kłopotliwe?
No właśnie, tutaj miałem małą zagwozdkę.
Jeżeli wartość enuma = jego nazwa, to trochę strzelamy sobie w kolano, bo potem w kodzie mamy:
Status::NEW-value // "NEW"
Status::NEW-name // "NEW"
A skoro można po prostu używać -name
, to po co nam to całe value
?
Zamiast tego lepiej zostawić zwykłe enum
(bez wartości) i mieć spokój.
⏳ A co było przed enumami?
Ach, stare dobre czasy…
Pisaliśmy takie kwiatki:
class Status {
public const NEW = 'new';
public const IN_PROGRESS = 'in_progress';
public const DONE = 'done';
}
$status = Status::NEW;
Albo jeszcze lepiej – tablice mapperów, które trzeba było utrzymywać w 3 miejscach naraz.
(Tak, wszyscy wiemy, że to bolało).
🔄 Before & After – czyli jak się pozbyłem mapperów
Przed (mappery):
class OrderStatus {
public const NEW = 'new';
public const IN_PROGRESS = 'in_progress';
public const DONE = 'done';
public static array $labels = [
self::NEW = "I'm doing things now!",
self::IN_PROGRESS = "I'm working on it!",
self::DONE = "I finished",
];
}
echo OrderStatus::$labels[OrderStatus::IN_PROGRESS]; // "I'm working on it!"
Po (enumy):
enum OrderStatus: string {
case NEW = 'new';
case IN_PROGRESS = 'in_progress';
case DONE = 'done';
public function label(): string {
return match($this) {
self::NEW = "I'm doing things now!",,
self::IN_PROGRESS = "I'm working on it!",
self::DONE = "I finished",
};
}
}
echo OrderStatus::IN_PROGRESS->label(); // "I'm working on it!"
Rezultat? Mappery out, kod jest czytelniejszy, a IDE podpowiada mi wszystko na bieżąco. 😎
Przykład jest ciut abstrakcyjny, ale mimo wszystko oddaje problemy, z którymi należy sobie radzić.
🎉 Moja mała rewolucja
Dzięki enumom udało mi się pozbyć całych mapperów wartości!
Teraz kod jest czytelniejszy, IDE podpowiada mi wartości, a ja śpię spokojnie. 🛌
Mappery? Nie, dziękuję.
Enumy przejęły pałeczkę i zrobiły to lepiej.
I serio – warto było to zrobić. 😎
📌 Podsumowanie
- PHP 8.1 dało nam enumy i BackedEnums.
- Używaj BackedEnums, gdy potrzebujesz mapowania nazw na wartości (
int
,string
). - Gdy
value == name
– rozważ zwykłeenum
. - Enumy = mniej bugów, mniej mapperów, więcej spokoju w duszy.
Morał: Enumy to takie nowe consty
, tylko ładniejsze i mądrzejsze.
Mappery możesz teraz wysłać na emeryturę. 🏖️
✍️ PS: Tak, uśmiechałem się, pisząc ten post. Bo naprawdę cieszę się, że w końcu mamy porządne enumy w PHP. ❤️
Podoba Ci się ten artykuł?
Oto kilka następnych artykułów, które mogą Ci się również spodobać: