PHP: My approach to saving Enum data values

Let me make a custom class to save them.

Italo Baeza Cabrera
2 min readMar 16, 2020
Photo by Croissant on Unsplash

After reading Salar’s way to “save” enum values, I decided to make my own way to save Enum values through a class called Enumerate.

The main task of an Enumerate instance is to allow to be set a valid state from a given list. If the state is not in the list, an Exception should be thrown because not doing so could break the application.

The idea is to let the class to hold a given number of possible “states”, and set one of these states using a dynamic call.

$enum = Enumerate::from([
'received', 'prepared', 'delivering', 'delivered'
]);
$enum->preparing();echo $enum; // "preparing"

That’s it. For safety, if you set an invalid state, you will get a BadMethodCallException.

Let’s check the class itself:

What about keys and values?

You can also create a state map, which is useful when you have simple states, but complex underlying values like class names, object instances or callables.

$enum = Enumerate::from([
'received' => Received::class,
'prepared' => Prepared::class,
'delivering' => Delivered::class,
'delivered' => fn($something) => App::make($something),
]);

When you set a set a state name, you will be also able to get the real value of the state instead of just the name with the value() method, among over handy helpers.

$enum->delivered();echo $enum->is('delivered'); // "true"
echo $enum->is('prepared'); // "false"
echo $enum->has('prepared'); // "true"
echo $enum->has('in-transit'); // "false"
echo $enum->current(); // "received"
echo $enum->value(); // "App\States\Received"

You can start an Enumerate instance initialized from the get go:

$enum = Enumerate::from(['foo', 'bar'], 'foo');

The good part of this class is you can extend it and add an initial value so it can be instanced with a default state already set.

class PackageStates extends Enumerate
{
protected $current = 'received';
protected $states = [
'received', 'prepared', 'delivering', 'delivered'
];
}

That’s it. No more need to hack your way into classes, use constants where you shouldn’t, or create obnoxious functions. Just imagine this:

public function notify(Package $package)
{
if ($package->is('delivered')) {
return 'Your package has been delivered already';
}
return 'Your package is on-transit to the destination';
}

--

--

Italo Baeza Cabrera

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor. https://italobc.com