What are possibilities of expressing enumerations in native PHP? And are there better options?
What to work with me? Say hello@jankuchar.cz
Libraries mentioned:
- grifart/enum: https://github.com/grifart/enum
- consistence/consistence: https://github.com/consistence/consistence/blob/master/docs/Enum/enums.md
- myclabs/php-enum: https://github.com/myclabs/php-enum
5. Contents
• Story: Project with an order, where state transitions are
restricted by domain
• Enum in laguages derived from C
• What is wrong with C-like implementations?
• Better alternatives for PHP
30. @honzakuchar
final class OrderState
{
public const RECEIVED = 'received';
public const PROCESSING = 'processing';
public const FINISHED = 'finished';
public const CANCELLED = 'cancelled';
}
31. @honzakuchar
function canDoTransition(string $currentState, string $desiredState): bool
{
switch ($currentState) {
case OrderState::RECEIVED:
return $desiredState === OrderState::PROCESSING
|| $desiredState === OrderState::CANCELLED;
case …
global function
41. @honzakuchar
final class OrderState extends Enum
{
protected const
RECEIVED = 'received',
PROCESSING = 'processing',
…
public function canDoTransition(OrderState $desiredState): bool
{
if ($this === self::RECEIVED()) {
return $desiredState === self::PROCESSING() || …;
}
…
throw new LogicException('Should not happen: Unknown state');
}
❌ There are still ugly ifs
which are hard to read.
42. @honzakuchar
final class OrderState extends Enum
{
protected const
RECEIVED = 'received',
PROCESSING = 'processing',
…
public function canDoTransition(OrderState $desiredState): bool
{
if ($this === self::RECEIVED()) {
return $desiredState === self::PROCESSING() || …;
}
…
throw new LogicException('Should not happen: Unknown state');
}
❌ I have to worry about case when someone
adds new value to this enum and forgets
to add switch case.