Creating Enumerations in PHP

Color EnumerationIf you are experienced in any of the major programming languages (.NET, Java, Python etc.) you are probably familiar with the idea of “Enums” or “Enumerations”. These are used to help increase readability by assigning readable names to a collection of static values. It is much easier to read “Color.Red” than seeing “#FF0000” or “1”. To expand on this idea imagine writing an if statement where you would compare a hex value to the color red…. if (“#FF0000” == Color.Red) { // Do stuff } seems to make a bit more sense and straight forward. Or perhaps you are comparing a value against multiple cases in a switch statement. It is easier to compare “#FF0000” against Color.Red, Color.Blue and Color.Green than “#FF0000”, “#00FF00” and “#0000FF” or “1”, “2” and “3”.

If you are familiar with enums, and with PHP, you probably are saying “Hey wait! PHP doesn’t have enums!” and you would be right. You get a gold star! But that doesn’t mean we couldn’t easily create them using a class. In this article I will quickly show you how we can create enums using a class and constants. In addition, I will show using reflection to look up an enumeration key given a value (which is often the reverse of why you use enums, but could still be warranted). Let’s get started!

Enumerations in PHP

To start off we are going to create a simple color enumeration which will list three colors: Red, Blue and Green. As with other languages you might know we would reference these color values like Color.Red, Color.Blue and Color.Green in our code. We wouldn’t have to create some kind of class instance or anything. Usually languages define their own enums as part of the language syntax and/or let you add your own. PHP on the other hand does not have this concept. So what we must do is use a class, an abstract class to be exact, to do what we want. For our various values, we will define some constants. This is how it may look…

abstract class Color {
   const RED = 1;
   const BLUE = 2;
   const GREEN = 3;
}

With an abstract class, we don’t need to create an instance of the class to get access to the variables it contains. With this definition we can begin using our enum class to compare against values 1, 2 and 3 to be RED, BLUE and GREEN respectively. Besides readability, why might we want to use an enum? Well, maybe we can only store the color as an integer in a database. We could store 1 in the database and then compare that value from the database to see if it is equal to Color.RED. Without this enum, we may not know that 1 is the representation of “red” in the database. It sounds silly not to just use a string in the database, but you would be surprised why things are never that straight forward… especially when working in a large organization with dozens of developers.

How To Use

Most of you familiar with Enums usually know that you use a period to access the values. For example Color.Blue or Color.Green. Since this is an abstract class and PHP’s resolution operator for access members of a class is :: then you would have to use Color::BLUE and Color::GREEN. Not too bad right?

Convert an Enum Value Into Its Key

As touched on in the beginning, most of the time you would use an Enum to compare some value you get from somewhere else to the enum’s values. Get the value from the database, compare it to Color.BLUE and then change the color of a page to blue in response. However, what about if we have a value like 3 and we want to know what color that is in our enum? Sure we could try that value against each of our three defined constants and have our answer. But what if we don’t know what all the constant values are? What if there are 20 constants? That would be a bit much to do 20 if/else statements or setup a switch with 20 cases. The code below takes a different approach. We use reflection to get the constants, loop through them and compare the values of each constant to the value we provide. If none is found, we return null.

function getConstantName($enum, $constantValue) {
    try {
        $reflection = new ReflectionClass($enum);
    } catch (ReflectionException $ex) {
        return null;
    }

    $constants = $reflection->getConstants();

    foreach ($constants as $key => $val) {
        if ($val === $constantValue) {
            return $key;
        }
    }

    return null;
}

With this code we could feed in our Color enumeration name and a value we are looking for and it will return the key. Make sure you give it a enum name or instance of our class that the function can see defined! For instance if we call getConstantName(‘Color’, 3); will return “GREEN”. You may or may not decide to use this functionality, but it is certainly something you could use if you were wondering if 3 even equals a color defined in our enum “Color”. If you use getConstantName(‘Color’, 6); you get a null back and know that it is not even a supported color and could default the color of the page to Color::Red.

Future Considerations

Now of course I know there is a ton of other things you may want to do with an enum. Heck you could even do something like mixing Color::BLUE and Color::YELLOW and want it to return Color::GREEN. The sky is the limit. Since we have created an abstract class there is no issues with moving your functions into the class and making them static methods. If you do a bit of searching on the web you can find others who mention an idea similar to this and take it in other directions including defining a base class and inheriting from that. I just wanted to provide you with a nice simple and easy to implement solution that will help you make your code much more readable. After all, readability is a key. We write code for other developers to read. 😉

Thanks for reading and keep up the coding!

About The Author

Martyr2 is the founder of the Coders Lexicon and author of the new ebooks "The Programmers Idea Book" and "Diagnosing the Problem" . He has been a programmer for over 25 years. He works for a hot application development company in Vancouver Canada which service some of the biggest tech companies in the world. He has won numerous awards for his mentoring in software development and contributes regularly to several communities around the web. He is an expert in numerous languages including .NET, PHP, C/C++, Java and more.