An overview of the

After N iterations, PHP enumeration library PHP-enum, which is very similar to Java enumeration definition, has been implemented in the latest version

It is worth mentioning here why Java enumerations are necessary. I knew about enumerations in Java, and I hadn’t heard of them in PHP for a long time, but enumerations were everywhere in Java projects, especially when the API returned a uniform state code, and they were becoming the norm, so I couldn’t ignore them, so I learned to use them, too. When I used PHP again, I found that I was not used to enumerations, so I decided to search for enumerations in PHP

As we all know, there are two options for using enumerations in PHP. One is the enumeration library that is officially available in SPL. Don’t worry, after reading the documentation, you will find that not only do you have to install it in an extended way, but the methods it provides are very limited. So we usually choose the second option, which is to use a third-party enumeration library. By reading the source code of third party enumerations, you will find that they have more or less the shadow of Java enumerations. But if they implemented Java enumerations there would be no libraries and articles today.

I looked at a number of enumerations and found that they lacked the core functionality of Java enumerations, which is customizing property values (in Java enumerations, instead of simply defining constant names and constant values, you can define properties to hold elements in enumerations). I also found it difficult to implement this functionality in PHP. So I wrote an abstract class in the project to fix two attributes, and since I wanted to use it in multiple projects, I put it on Github, and after many refactorings, I finally got close to the implementation of Java enumeration

The installation

composer require phpenum/phpenum
Copy the code

Quick start

PHPEnum is used much like Java enumerations, such as defining an enumeration that represents a gender

In Java:

public enum GenderEnum { MALE(1, "male"), FEMALE(2, "female"); private Integer id; private String name; GenderEnum(Integer id, String name) { this.id = id; this.name = name; } public Integer getId() { return id; } public String getName() { return name; }}Copy the code

Using PhpEnum:

class GenderEnum extends \PhpEnum\Enum { const MALE = [1, 'male']; const FEMALE = [2, 'female']; private $id; private $name; protected function construct($id, $name) { $this->id = $id; $this->name->$name; } public function getId() { return $this->id; } public function getName() { return $this->name; }}Copy the code

You’ll notice that they’re very similar in usage

In Java:

GenderEnum.values(); // enum instance array
GenderEnum.valueOf("FEMALE"); // enum instance
GenderEnum.MALE.equals(GenderEnum.valueOf("MALE")); // true
GenderEnum.MALE.name(); // MALE
GenderEnum.MALE.ordinal(); // 0
GenderEnum.MALE.toString(); // MALE
GenderEnum.MALE.getId(); // 1
GenderEnum.MALE.getName(); // male
Copy the code

Using PhpEnum:

GenderEnum::values(); // enum instance array
GenderEnum::valueOf('FEMALE'); // enum instance
GenderEnum::MALE()->equals(GenderEnum::valueOf('MALE')); // true
GenderEnum::MALE()->name(); // MALE
GenderEnum::MALE()->ordinal(); // 0
(string)GenderEnum::MALE(); // MALE
GenderEnum::MALE()->getId(); // 1
GenderEnum::MALE()->getName(); // male
Copy the code

Not only that, PhpEnum also provides advanced functionality in subclasses

GenderEnum::MALE()->idEquals(1); // true
GenderEnum::MALE()->NameEquals('male'); // true
GenderEnum::containsId(1); // 1
GenderEnum::containsName('male'); // 1
GenderEnum::ofId(1); // enum instance
GenderEnum::ofName('male'); // enum instance
Copy the code

PHPEnum is a library of enumerated classes for PHP developers. It consists of the base Enum class and the extended PHPEnum class. The base class fully references Java enumerations and implements similar functionality. And the extension class is through the combination of PHP language features to achieve some fast access methods.

Base class Enum

The base class references Java enumerations entirely, and if you know Java enumerations before, you can use them in the same way here.

The format of an enumeration constant defined in Java is a call to a constructor parameter. In the absence of arguments, parentheses and constructors can be omitted. In the presence of arguments, a constructor corresponding to the parameter format must be provided.

Ex. :

Public enum Color {RED, GREEN, BLUE; } public enum Color {RED("FF0000"), GREEN("00FF00"), BLUE("0000FF"); Color(String hexadecimal) { } }Copy the code

In PHP, however, PHP syntax does not allow this, so PhpEnum uses a constant array to represent arguments in a constructor. The constructor can be omitted if there are no arguments, but the array of arguments cannot be omitted. If there are arguments, you must provide a constructor corresponding to the format of the argument.

The constructor in PhpEnum is namedconstructAnd must useprotectedTo modify

Ex. :

Class Color extends \PhpEnum\Enum {const RED = []; const GREEN = []; const BLUE = []; } class Color extends \PhpEnum\Enum {const RED = ["FF0000"]; const GREEN = ["00FF00"]; const BLUE = ["0000FF"]; protected function construct(string $hexadecimal) { } }Copy the code

In practice, we usually need to define parameters and their corresponding properties and getters to make them accessible to the outside world

Ex. :

class Color extends \PhpEnum\Enum { const RED = ["FF0000"]; const GREEN = ["00FF00"]; const BLUE = ["0000FF"]; private string $hexadecimal; protected function construct(string $hexadecimal) { $this->hexadecimal = $hexadecimal; } public function getHexadecimal(): string { return $this->hexadecimal; }}Copy the code

The base class gives us the following methods

  • Name :string Returns the name of the enumeration
  • Ordinal :int Returns the order of the enumeration definition, starting at 0
  • Equals :bool Compares equals with another enumeration
  • Static values: Static [] returns all instances of enumerations. Proper use of the prefix argument can reduce memory overhead and return the correct result if the same enumeration values exist, although it is not recommended to define the same values in the same enumeration
  • Static valueOf:static Returns an enumeration instance based on the enumeration name

Expand the class PhpEnum

An extended class is a subclass of the base class, so it is defined and used exactly the same way as the base class, and provides more ways to use enumerations. Most of the methods provided by extended classes are related to enumerated properties, so you should define properties and their getters correctly when using extended classes.

Ex. :

class Color extends \PhpEnum\PhpEnum { const RED = ["FF0000"]; const GREEN = ["00FF00"]; const BLUE = ["0000FF"]; private string $hexadecimal; protected function construct(string $hexadecimal) { $this->hexadecimal = $hexadecimal; } public function getHexadecimal(): string { return $this->hexadecimal; }}Copy the code

The extension class provides us with the following methods

  • Get :mixed gets an attribute value. Note that this method is not a substitute for the getter for a property. Instead, when you use a private modifier for a property, you should provide the getter for the property to ensure that the method is correct. This is the basis for other methods (although it is possible to get the value of the property through reflection, which incurs a large memory overhead).
  • EnumNameEquals :bool Determines whether the enumeration name is equal to the specified name
  • PropertyEquals :bool Specifies whether the enumerated property value is equal to the specified property value. Note that bccomp is used for comparison when the property type is floating point. You need to override the scale method to set the correct decimal number
  • Static containsEnumName:bool Indicates whether the enumeration name contains the specified enumeration name
  • Static containsProperty:int Returns the number of enumerations whose value is equal to the specified value
  • Static ofProperty: Static returns an enumeration instance whose enumeration property value is equal to the specified value. When the number of enumerations found is greater than 1, an exception is thrown
  • Static Properties :array Returns an array of all enumerated values for a property
  • Static names:string[] Returns all enumeration names
  • Static count:int Returns the number of enumerations

The extension class provides a way to trigger the equals, Contains, and of magic methods, which automatically find the correct method call when the method contains the keyword and property name.

Ex. :

var_dump(Color::RED()->hexadecimalEquals('FF0000')); // bool(true)
var_dump(Color::containsHexadecimal('FF0000')); // int(1)
var_dump(Color::ofHexadecimal('FF0000')); // object(Color)
Copy the code