- nelexa/enum - Enum implementation for PHP
- Table of Contents
- Installation
- Enum declaration
- Usage
- Class Synopsis
- Usage tips
- Generate PHPDoc for enum class
- Changelog
- License
composer require nelexa/enum<?phpuseNelexa\Enum;
/** * @method static self PENDING() * @method static self ACTIVE() * @method static self INACTIVE() * @method static self DELETED() */class UserStatus extends Enum
{
publicconstPENDING = 1,
ACTIVE = 1 << 1,
INACTIVE = 1 << 2,
DELETED = 1 << 3;
}$enum = UserStatus::ACTIVE();
assert($enuminstanceof UserStatus);
assert($enum->name() === 'ACTIVE');
assert($enum->value() === 1 << 1);
assert($enum->ordinal() === 1);foreach (UserStatus::values() as$userStatus) {
printf('User status: %s, status id: %d, ordinal: %d' . PHP_EOL,
$userStatus->name(),
$userStatus->value(),
$userStatus->ordinal()
);
}Output:
User status: PENDING, status id: 1, ordinal: 0
User status: ACTIVE, status id: 2, ordinal: 1
User status: INACTIVE, status id: 4, ordinal: 2
User status: DELETED, status id: 8, ordinal: 3
$userStatus = UserStatus::DELETED();
if ($userStatus === UserStatus::DELETED()) {
echo'User status: ' . $userStatus->name() . PHP_EOL;
}$enum = UserStatus::valueOf('ACTIVE');
assert(UserStatus::ACTIVE() === UserStatus::valueOf('ACTIVE'));$enum = UserStatus::valueOf('ACTIVE');
$value = $enum->value();
assert(UserStatus::fromValue($value) === $enum);
assert(UserStatus::fromValue($value) === UserStatus::valueOf('ACTIVE'));$enum = UserStatus::PENDING();
switch ($enum) {
case UserStatus::ACTIVE():
echo'Active status';
break;
case UserStatus::PENDING():
echo'Pending status';
break;
case UserStatus::DELETED():
echo'Delete status';
break;
case UserStatus::INACTIVE():
echo'Inactive status';
break;
default:
thrownew \RuntimeException('Invalid value');
}Output:
Pending status
/** * @var UserStatus */private$status;
publicfunctionsetStatus(UserStatus$status): void
{
$this->status = $status;
}
publicfunctiongetStatus(): UserStatus
{
return$this->status;
}
publicfunctionisActive(): bool
{
return$this->status === UserStatus::ACTIVE();
}Example
$user->setStatus(UserStatus::INACTIVE());
echosprintf('User status is %s.' . PHP_EOL, $user->getStatus()->name());Output:
User status is INACTIVE
<?php/** * @method static self PLUS() * @method static self MINUS() * @method static self TIMES() * @method static self DIVIDE() */class Operation extends \Nelexa\Enum
{
privateconstPLUS = null,
MINUS = null,
TIMES = null,
DIVIDE = null;
/** * Do arithmetic op represented by this constant * * @param float $x * @param float $y * @return float */publicfunctioncalculate(float$x, float$y): float
{
switch ($this) {
caseself::PLUS():
return$x + $y;
caseself::MINUS():
return$x - $y;
caseself::TIMES():
return$x * $y;
caseself::DIVIDE():
return$x / $y;
}
thrownew \AssertionError('Unknown op: ' . $this->name());
}
}Example
echo Operation::PLUS()->calculate(4, 2); // 6echo Operation::TIMES()->calculate(4, 2); // 8echo Operation::MINUS()->calculate(4, 2); // 2echo Operation::DIVIDE()->calculate(4, 2); // 2For example consider the planets of the solar system. Each planet knows its mass and radius, and can calculate its surface gravity and the weight of an object on the planet.
Here is how it looks:
<?phpdeclare(strict_types=1);
useNelexa\Enum;
/** * Class Planet * * @method static self MERCURY() * @method static self VENUS() * @method static self EARTH() * @method static self MARS() * @method static self JUPITER() * @method static self SATURN() * @method static self URANUS() * @method static self NEPTUNE() * @method static self PLUTO() * * @see https://docs.oracle.com/javase/8/docs/technotes/guides/language/enums.html */class Planet extends Enum
{
privateconstMERCURY = [3.303e+23, 2.4397e6],
VENUS = [4.869e+24, 6.0518e6],
EARTH = [5.976e+24, 6.37814e6],
MARS = [6.421e+23, 3.3972e6],
JUPITER = [1.9e+27, 7.1492e7],
SATURN = [5.688e+26, 6.0268e7],
URANUS = [8.686e+25, 2.5559e7],
NEPTUNE = [1.024e+26, 2.4746e7],
PLUTO = [1.27e+22, 1.137e6];
/** * @var double universal gravitational constant (m3 kg-1 s-2) */privatestatic$G = 6.67300E-11;
/** * @var double in kilograms */private$mass;
/** * @var double in meters */private$radius;
/** * In this method, you can initialize additional variables based on the * value of the constant. The method is called after the constructor. * * @param string|int|float|bool|array|null $value the enum scalar value of the constant */protectedfunctioninitValue($value): void
{
[$this->mass, $this->radius] = $value;
}
publicfunctionmass(): float
{
return$this->mass;
}
publicfunctionradius(): float
{
return$this->radius;
}
publicfunctionsurfaceGravity(): float
{
returnself::$G * $this->mass / ($this->radius * $this->radius);
}
publicfunctionsurfaceWeight(float$otherMass): float
{
returnround($otherMass * $this->surfaceGravity(), 6);
}
}The enum Planet class contains the initValue($value) method, and each enum constant is declared with a value that to be passed to this method when it is created.
Here is a sample program that takes your weight on earth (in any unit) and calculates and prints your weight on all of the planets (in the same unit):
$earthWeight = 175;
$mass = $earthWeight / Planet::EARTH()->surfaceGravity();
foreach (Planet::values() as$p) {
printf("Your weight on %s is %f\n", $p->name(), $p->surfaceWeight($mass));
}Output:
Your weight on MERCURY is 66.107583
Your weight on VENUS is 158.374842
Your weight on EARTH is 175.000000
Your weight on MARS is 66.279007
Your weight on JUPITER is 442.847567
Your weight on SATURN is 186.552719
Your weight on URANUS is 158.397260
Your weight on NEPTUNE is 199.207413
Your weight on PLUTO is 11.703031
abstractclass Nelexa\Enum {
/* Methods */finalpublicstatic valueOf ( string$name ) : static
finalpublic name ( void ) : string
finalpublic value ( void ) : string | int | float | bool | array | nullfinalpublicstatic values ( void ) : static[]
finalpublicstaticcontainsKey ( string $name ) : bool
finalpublicstatic containsValue ( mixed$value [, bool$strict = true ] ) : bool
finalpublicstaticfunction fromValue( mixed$value ): static
final public ordinal ( void ) : int
public __toString ( void ) : string
protected static functiongetEnumConstants(): array
}- Even though it is not mandatory to declare enum constants with UPPERCASE letters, it is in the best practice to do so.
- Enum classes can have fields and methods along with enum constants.
- Enum constructors are private. Only private constructors are allowed in enum classes. That’s why you can’t instantiate enum types using a new operator.
- Enum constants are created only once for the whole execution. All enum constants are created when you initially refer any enum constant in your code.
- Enum types can implement any number of interfaces.
- We can compare the enum constants using the
===operator. - You can retrieve the enum constants of any enum type using the
values()static method. Thevalues()static method returns an array of enum constants. - The
ordinal()static method is used to get the order of an enum constant in an enum type. - Enums are mostly used when you want to allow a limited set of options that remain constant for the whole execution and you know all possible options. For example, this could be choices on a menu or options of a combobox.
- Use private constants to exclude prompts from your IDE.
- Use PHPDoc to describe static enum initialization methods.
To use hints in the IDE, you need to declare special comments on the class with a list of static methods.
The \Nelexa\enum_docblock($enumOrEnumClass) function should help with this.
echo\Nelexa\enum_docblock(Planet::class);
// orecho\Nelexa\enum_docblock(Planet::MERCURY());Output:
/**
* @method static self MERCURY()
* @method static self VENUS()
* @method static self EARTH()
* @method static self MARS()
* @method static self JUPITER()
* @method static self SATURN()
* @method static self URANUS()
* @method static self NEPTUNE()
* @method static self PLUTO()
*/
Changes are documented in the releases page.
The files in this archive are released under the MIT License.
You can find a copy of this license in LICENSE file.


