Vendor\MyEnum.php
<?php declare(strict_types=1);
if (PHP_VERSION_ID < 80100) {
require_once __DIR__ . '/MyEnum-emulated.php';
} else {
require_once __DIR__ . '/MyEnum-native.php';
}
Vendor\MyEnum-emulated.php
<?php declare(strict_types=1);
namespace Vendor;
use Mabe\Enum\Cl\EmulatedIntEnum;
final class MyEnum extends EmulatedIntEnum
{
protected const ZERO = 0;
protected const ONE = 1;
protected const TWO = 2;
protected const THREE = 3;
protected const FOUR = 4;
protected const FIVE = 5;
protected const SIX = 6;
protected const SEVEN = 7;
protected const EIGHT = 8;
protected const NINE = 9;
}
Vendor\MyEnum-native.php
<?php declare(strict_types=1);
namespace Vendor;
use Mabe\Enum\Cl\EnumBc;
enum MyEnum:int
{
use EnumBc;
case ZERO = 0;
case ONE = 1;
case TWO = 2;
case THREE = 3;
case FOUR = 4;
case FIVE = 5;
case SIX = 6;
case SEVEN = 7;
case EIGHT = 8;
case NINE = 9;
}
Enum type | native | emulated |
---|---|---|
Unit enum | enum ENUMNAME { |
final class ENUMNAME extends \Mabe\Enum\Cl\EmulatedUnitEnum { |
Integer backed enum | enum ENUMNAME:int { |
final class ENUMNAME extends \Mabe\Enum\Cl\EmulatedIntEnum { |
String backed enum | enum ENUMNAME:string { |
final class ENUMNAME extends \Mabe\Enum\Cl\EmulatedStringEnum { |
For IDE and static code analyzers I recommend adding the following docblock:
/**
* @method static self CASENAME()
*/
The following will work the same on PHP<8.1 (using emulated enums) and on PHP>=8.1 (using native enums):
<?php declare(strict_types=1);
namespace Vendor;
use function Mabe\Enum\Cl\enum_exists;
$zero = MyEnum::ZERO();
$zero = MyEnum::from(0);
$zero = MyEnum::tryFrom(0);
$cases = MyEnum::cases();
$zero->value; // 0
$zero->name; // ZERO
$zero instanceof \UnitEnum; // true
$zero instanceof \BackedEnum; // true
MyEnum::ZERO() === MyEnum::from(0); // true
MyEnum::from(0) === MyEnum::tryFrom(0); // true
enum_exists(MyEnum::class); // true
enum_exists('stdClass'); // false
Warning: The following will not behave the same on all PHP versions:
<?php declare(strict_types=1);
namespace Vendor;
MyEnum::ZERO; // PHP<8.1: Error: Cannot access protected const MyEnum::ZERO
// PHP>=8.1: enum(MyEnum::ZERO)
serialize(MyEnum::ZERO()); // PHP<8.1: Error: Trying to serialize a non serializable emulated enum case of MyEnum
// PHP>=8.1: "E:11:"MyEnum:ZERO"
By default PHPStan will complain about unused constants as it can't automatically detect the special use via reflection in this case.
To avoid this you need to add the following to your phpstan.neon[.dist]
:
services:
-
class: Mabe\Enum\Cl\PHPStan\ConstantExtension
tags:
- phpstan.constants.alwaysUsedClassConstantsExtension
For more information please read https://phpstan.org/developing-extensions/always-used-class-constants
This library includes the following polyfills (if not already present):
get_debug_type