README.md
165 lines
| 1 | # PHP 7.1 enums |
| 2 | |
| 3 | [](https://github.com/DASPRiD/Enum/actions?query=workflow%3Atests](https://github.com/DASPRiD/Enum/actions?query=workflow%3Atests](https://github.com/DASPRiD/Enum/actions?query=workflow%3Atests) |
| 4 | [](https://coveralls.io/github/DASPRiD/Enum?branch=master](https://coveralls.io/github/DASPRiD/Enum?branch=master](https://coveralls.io/github/DASPRiD/Enum?branch=master) |
| 5 | [](https://packagist.org/packages/dasprid/enum](https://packagist.org/packages/dasprid/enum](https://packagist.org/packages/dasprid/enum) |
| 6 | [](https://packagist.org/packages/dasprid/enum](https://packagist.org/packages/dasprid/enum](https://packagist.org/packages/dasprid/enum) |
| 7 | [](https://packagist.org/packages/dasprid/enum](https://packagist.org/packages/dasprid/enum](https://packagist.org/packages/dasprid/enum) |
| 8 | |
| 9 | It is a well known fact that PHP is missing a basic enum type, ignoring the rather incomplete `SplEnum` implementation |
| 10 | which is only available as a PECL extension. There are also quite a few other userland enum implementations around, |
| 11 | but all of them have one or another compromise. This library tries to close that gap as far as PHP allows it to. |
| 12 | |
| 13 | ## Usage |
| 14 | |
| 15 | ### Basics |
| 16 | |
| 17 | At its core, there is the `DASPRiD\Enum\AbstractEnum` class, which by default will work with constants like any other |
| 18 | enum implementation you might know. The first clear difference is that you should define all the constants as protected |
| 19 | (so nobody outside your class can read them but the `AbstractEnum` can still do so). The other even mightier difference |
| 20 | is that, for simple enums, the value of the constant doesn't matter at all. Let's have a look at a simple example: |
| 21 | |
| 22 | ```php |
| 23 | use DASPRiD\Enum\AbstractEnum; |
| 24 | |
| 25 | /** |
| 26 | * @method static self MONDAY() |
| 27 | * @method static self TUESDAY() |
| 28 | * @method static self WEDNESDAY() |
| 29 | * @method static self THURSDAY() |
| 30 | * @method static self FRIDAY() |
| 31 | * @method static self SATURDAY() |
| 32 | * @method static self SUNDAY() |
| 33 | */ |
| 34 | final class WeekDay extends AbstractEnum |
| 35 | { |
| 36 | protected const MONDAY = null; |
| 37 | protected const TUESDAY = null; |
| 38 | protected const WEDNESDAY = null; |
| 39 | protected const THURSDAY = null; |
| 40 | protected const FRIDAY = null; |
| 41 | protected const SATURDAY = null; |
| 42 | protected const SUNDAY = null; |
| 43 | } |
| 44 | ``` |
| 45 | |
| 46 | If you need to provide constants for either internal use or public use, you can mark them as either private or public, |
| 47 | in which case they will be ignored by the enum, which only considers protected constants as valid values. As you can |
| 48 | see, we specifically defined the generated magic methods in a class level doc block, so anyone using this class will |
| 49 | automatically have proper auto-completion in their IDE. Now since you have defined the enum, you can simply use it like |
| 50 | that: |
| 51 | |
| 52 | ```php |
| 53 | function tellItLikeItIs(WeekDay $weekDay) |
| 54 | { |
| 55 | switch ($weekDay) { |
| 56 | case WeekDay::MONDAY(): |
| 57 | echo 'Mondays are bad.'; |
| 58 | break; |
| 59 | |
| 60 | case WeekDay::FRIDAY(): |
| 61 | echo 'Fridays are better.'; |
| 62 | break; |
| 63 | |
| 64 | case WeekDay::SATURDAY(): |
| 65 | case WeekDay::SUNDAY(): |
| 66 | echo 'Weekends are best.'; |
| 67 | break; |
| 68 | |
| 69 | default: |
| 70 | echo 'Midweek days are so-so.'; |
| 71 | } |
| 72 | } |
| 73 | |
| 74 | tellItLikeItIs(WeekDay::MONDAY()); |
| 75 | tellItLikeItIs(WeekDay::WEDNESDAY()); |
| 76 | tellItLikeItIs(WeekDay::FRIDAY()); |
| 77 | tellItLikeItIs(WeekDay::SATURDAY()); |
| 78 | tellItLikeItIs(WeekDay::SUNDAY()); |
| 79 | ``` |
| 80 | |
| 81 | ### More complex example |
| 82 | |
| 83 | Of course, all enums are singletons, which are not cloneable or serializable. Thus you can be sure that there is always |
| 84 | just one instance of the same type. Of course, the values of constants are not completely useless, let's have a look at |
| 85 | a more complex example: |
| 86 | |
| 87 | ```php |
| 88 | use DASPRiD\Enum\AbstractEnum; |
| 89 | |
| 90 | /** |
| 91 | * @method static self MERCURY() |
| 92 | * @method static self VENUS() |
| 93 | * @method static self EARTH() |
| 94 | * @method static self MARS() |
| 95 | * @method static self JUPITER() |
| 96 | * @method static self SATURN() |
| 97 | * @method static self URANUS() |
| 98 | * @method static self NEPTUNE() |
| 99 | */ |
| 100 | final class Planet extends AbstractEnum |
| 101 | { |
| 102 | protected const MERCURY = [3.303e+23, 2.4397e6]; |
| 103 | protected const VENUS = [4.869e+24, 6.0518e6]; |
| 104 | protected const EARTH = [5.976e+24, 6.37814e6]; |
| 105 | protected const MARS = [6.421e+23, 3.3972e6]; |
| 106 | protected const JUPITER = [1.9e+27, 7.1492e7]; |
| 107 | protected const SATURN = [5.688e+26, 6.0268e7]; |
| 108 | protected const URANUS = [8.686e+25, 2.5559e7]; |
| 109 | protected const NEPTUNE = [1.024e+26, 2.4746e7]; |
| 110 | |
| 111 | /** |
| 112 | * Universal gravitational constant. |
| 113 | * |
| 114 | * @var float |
| 115 | */ |
| 116 | private const G = 6.67300E-11; |
| 117 | |
| 118 | /** |
| 119 | * Mass in kilograms. |
| 120 | * |
| 121 | * @var float |
| 122 | */ |
| 123 | private $mass; |
| 124 | |
| 125 | /** |
| 126 | * Radius in meters. |
| 127 | * |
| 128 | * @var float |
| 129 | */ |
| 130 | private $radius; |
| 131 | |
| 132 | protected function __construct(float $mass, float $radius) |
| 133 | { |
| 134 | $this->mass = $mass; |
| 135 | $this->radius = $radius; |
| 136 | } |
| 137 | |
| 138 | public function mass() : float |
| 139 | { |
| 140 | return $this->mass; |
| 141 | } |
| 142 | |
| 143 | public function radius() : float |
| 144 | { |
| 145 | return $this->radius; |
| 146 | } |
| 147 | |
| 148 | public function surfaceGravity() : float |
| 149 | { |
| 150 | return self::G * $this->mass / ($this->radius * $this->radius); |
| 151 | } |
| 152 | |
| 153 | public function surfaceWeight(float $otherMass) : float |
| 154 | { |
| 155 | return $otherMass * $this->surfaceGravity(); |
| 156 | } |
| 157 | } |
| 158 | |
| 159 | $myMass = 80; |
| 160 | |
| 161 | foreach (Planet::values() as $planet) { |
| 162 | printf("Your weight on %s is %f\n", $planet, $planet->surfaceWeight($myMass)); |
| 163 | } |
| 164 | ``` |
| 165 |