language/enumerations.xml
3bc8fc7b9785c335e55d83986e6cd8968498dcfb
...
...
@@ -6,15 +6,15 @@
6
6
<?phpdoc print-version-for="enumerations"?>
7
7

8
8
<para>
9
-
Enumerations, or "Enums" allow a developer to define a custom type that is limited to one
10
-
of a discrete number of possible values. That can be especially helpful when defining a
9
+
Enumerations, or "Enums", allow a developer to define a custom type that is limited to one
10
+
of a discrete number of possible values. That can be especially helpful when defining a
11
11
domain model, as it enables "making invalid states unrepresentable."
12
12
</para>
13
13

14
14
<para>
15
15
Enums appear in many languages with a variety of different features. In PHP,
16
-
Enums are a special kind of object. The Enum itself is a class, and its possible
17
-
cases are all single-instance objects of that class. That means Enum cases are
16
+
Enums are a special kind of object. The Enum itself is a class, and its possible
17
+
cases are all single-instance objects of that class. That means Enum cases are
18
18
valid objects and may be used anywhere an object may be used, including type checks.
19
19
</para>
20
20

...
...
@@ -37,6 +37,7 @@
37
37
<programlisting role="php">
38
38
<![CDATA[
39
39
<?php
40
+

40
41
enum Suit
41
42
{
42
43
case Hearts;
...
...
@@ -59,14 +60,20 @@ enum Suit
59
60
<programlisting role="php">
60
61
<![CDATA[
61
62
<?php
62
-
function pick_a_card(Suit $suit) { ... }
63
+

64
+
function pick_a_card(Suit $suit)
65
+
{
66
+
/* ... */
67
+
}
63
68

64
69
$val = Suit::Diamonds;
65
70

66
71
// OK
67
72
pick_a_card($val);
73
+

68
74
// OK
69
75
pick_a_card(Suit::Clubs);
76
+

70
77
// TypeError: pick_a_card(): Argument #1 ($suit) must be of type Suit, string given
71
78
pick_a_card('Spades');
72
79
?>
...
...
@@ -91,6 +98,7 @@ pick_a_card('Spades');
91
98
<programlisting role="php">
92
99
<![CDATA[
93
100
<?php
101
+

94
102
$a = Suit::Spades;
95
103
$b = Suit::Spades;
96
104

...
...
@@ -103,8 +111,8 @@ $a instanceof Suit; // true
103
111

104
112
<para>
105
113
It also means that enum values are never <literal>&lt;</literal> or <literal>&gt;</literal> each other,
106
-
since those comparisons are not meaningful on objects. Those comparisons will always return
107
-
false when working with enum values.
114
+
since those comparisons are not meaningful on objects. Those comparisons will always return
115
+
&false; when working with enum values.
108
116
</para>
109
117

110
118
<para>
...
...
@@ -113,7 +121,7 @@ $a instanceof Suit; // true
113
121
</para>
114
122

115
123
<para>
116
-
All Pure Cases are implemented as instances of their enum type. The enum type is represented internally as a class.
124
+
All Pure Cases are implemented as instances of their enum type. The enum type is represented internally as a class.
117
125
</para>
118
126

119
127
<para>
...
...
@@ -124,12 +132,20 @@ $a instanceof Suit; // true
124
132
<programlisting role="php">
125
133
<![CDATA[
126
134
<?php
135
+

127
136
print Suit::Spades->name;
128
137
// prints "Spades"
129
138
?>
130
139
]]>
131
140
</programlisting>
132
141

142
+
<para>
143
+
It is also possible to use the <function>defined</function> and <function>constant</function>
144
+
functions to check for the existence of or read an enum case if the name is obtained dynamically.
145
+
This is, however, discouraged as using <link linkend="language.enumerations.backed">Backed enums</link>
146
+
should work for most use cases.
147
+
</para>
148
+

133
149
</sect1>
134
150

135
151
<sect1 xml:id="language.enumerations.backed">
...
...
@@ -147,6 +163,7 @@ print Suit::Spades->name;
147
163
<programlisting role="php">
148
164
<![CDATA[
149
165
<?php
166
+

150
167
enum Suit: string
151
168
{
152
169
case Hearts = 'H';
...
...
@@ -160,23 +177,25 @@ enum Suit: string
160
177

161
178
<para>
162
179
A case that has a scalar equivalent is called a Backed Case, as it is "Backed"
163
-
by a simpler value. An Enum that contains all Backed Cases is called a "Backed Enum."
164
-
A Backed Enum may contain only Backed Cases. A Pure Enum may contain only Pure Cases.
180
+
by a simpler value. An Enum that contains all Backed Cases is called a "Backed Enum."
181
+
A Backed Enum may contain only Backed Cases. A Pure Enum may contain only Pure Cases.
165
182
</para>
166
183

167
184
<para>
168
185
A Backed Enum may be backed by types of <literal>int</literal> or <literal>string</literal>,
169
186
and a given enumeration supports only a single type at a time (that is, no union of <literal>int|string</literal>).
170
187
If an enumeration is marked as having a scalar equivalent, then all cases must have a unique
171
-
scalar equivalent defined explicitly. There are no auto-generated scalar equivalents
172
-
(e.g., sequential integers). Backed cases must be unique; two backed enum cases may
173
-
not have the same scalar equivalent. However, a constant may refer to a case, effectively
174
-
creating an alias. See <link linkend="language.enumerations.constants">Enumeration constants</link>.
188
+
scalar equivalent defined explicitly. There are no auto-generated scalar equivalents
189
+
(e.g., sequential integers). Backed cases must be unique; two backed enum cases may
190
+
not have the same scalar equivalent. However, a constant may refer to a case, effectively
191
+
creating an alias. See <link linkend="language.enumerations.constants">Enumeration constants</link>.
175
192
</para>
176
193

177
194
<para>
178
-
Equivalent values must be literals or literal expressions. Constants and constant expressions
179
-
are not supported. That is, <literal>1 + 1</literal> is allowed, but <literal>1 + SOME_CONST</literal>
195
+
The equivalent values may be a constant scalar expression.
196
+
Prior to PHP 8.2.0, the equivalent values had to be literals or literal expressions.
197
+
This means that constants and constant expressions were not supported.
198
+
That is, <code>1 + 1</code> was allowed, but not <code>1 + SOME_CONST</code>.
180
199
is not.
181
200
</para>
182
201

...
...
@@ -188,6 +207,7 @@ enum Suit: string
188
207
<programlisting role="php">
189
208
<![CDATA[
190
209
<?php
210
+

191
211
print Suit::Clubs->value;
192
212
// Prints "C"
193
213
?>
...
...
@@ -196,12 +216,13 @@ print Suit::Clubs->value;
196
216

197
217
<para>
198
218
In order to enforce the <literal>value</literal> property as read-only, a variable cannot
199
-
be assigned as a reference to it. That is, the following throws an error:
219
+
be assigned as a reference to it. That is, the following throws an error:
200
220
</para>
201
221

202
222
<programlisting role="php">
203
223
<![CDATA[
204
224
<?php
225
+

205
226
$suit = Suit::Clubs;
206
227
$ref = &$suit->value;
207
228
// Error: Cannot acquire reference to property Suit::$value
...
...
@@ -217,13 +238,13 @@ $ref = &$suit->value;
217
238
<simplelist>
218
239
<member>
219
240
<literal>from(int|string): self</literal> will take a scalar and return the corresponding
220
-
Enum Case. If one is not found, it will throw a <classname>ValueError</classname>. This is mainly
241
+
Enum Case. If one is not found, it will throw a <classname>ValueError</classname>. This is mainly
221
242
useful in cases where the input scalar is trusted and a missing enum value should be
222
243
considered an application-stopping error.
223
244
</member>
224
245
<member>
225
246
<literal>tryFrom(int|string): ?self</literal> will take a scalar and return the
226
-
corresponding Enum Case. If one is not found, it will return <literal>null</literal>.
247
+
corresponding Enum Case. If one is not found, it will return <literal>null</literal>.
227
248
This is mainly useful in cases where the input scalar is untrusted and the caller wants
228
249
to implement their own error handling or default-value logic.
229
250
</member>
...
...
@@ -231,17 +252,18 @@ $ref = &$suit->value;
231
252

232
253
<para>
233
254
The <literal>from()</literal> and <literal>tryFrom()</literal> methods follow standard
234
-
weak/strong typing rules. In weak typing mode, passing an integer or string is acceptable
235
-
and the system will coerce the value accordingly. Passing a float will also work and be
236
-
coerced. In strict typing mode, passing an integer to <literal>from()</literal> on a
255
+
weak/strong typing rules. In weak typing mode, passing an integer or string is acceptable
256
+
and the system will coerce the value accordingly. Passing a float will also work and be
257
+
coerced. In strict typing mode, passing an integer to <literal>from()</literal> on a
237
258
string-backed enum (or vice versa) will result in a <classname>TypeError</classname>,
238
-
as will a float in all circumstances. All other parameter types will throw a TypeError
259
+
as will a float in all circumstances. All other parameter types will throw a TypeError
239
260
in both modes.
240
261
</para>
241
262

242
263
<programlisting role="php">
243
264
<![CDATA[
244
265
<?php
266
+

245
267
$record = get_stuff_from_database($id);
246
268
print $record['suit'];
247
269

...
...
@@ -272,6 +294,7 @@ print $suit->value;
272
294
<programlisting role="php">
273
295
<![CDATA[
274
296
<?php
297
+

275
298
interface Colorful
276
299
{
277
300
public function color(): string;
...
...
@@ -300,7 +323,10 @@ enum Suit implements Colorful
300
323
}
301
324
}
302
325

303
-
function paint(Colorful $c) { ... }
326
+
function paint(Colorful $c)
327
+
{
328
+
/* ... */
329
+
}
304
330

305
331
paint(Suit::Clubs); // Works
306
332

...
...
@@ -311,7 +337,7 @@ print Suit::Diamonds->shape(); // prints "Rectangle"
311
337

312
338
<para>
313
339
In this example, all four instances of <literal>Suit</literal> have two methods,
314
-
<literal>color()</literal> and <literal>shape()</literal>. As far as calling code
340
+
<literal>color()</literal> and <literal>shape()</literal>. As far as calling code
315
341
and type checks are concerned, they behave exactly the same as any other object instance.
316
342
</para>
317
343

...
...
@@ -322,6 +348,7 @@ print Suit::Diamonds->shape(); // prints "Rectangle"
322
348
<programlisting role="php">
323
349
<![CDATA[
324
350
<?php
351
+

325
352
interface Colorful
326
353
{
327
354
public function color(): string;
...
...
@@ -353,7 +380,7 @@ enum Suit: string implements Colorful
353
380

354
381
<para>
355
382
Methods may be arbitrarily complex, but in practice will usually return a static value or
356
-
<link linkend="control-structures.match">match</link> on <literal>$this</literal> to provide
383
+
&match; on <literal>$this</literal> to provide
357
384
different results for different cases.
358
385
</para>
359
386

...
...
@@ -371,6 +398,7 @@ enum Suit: string implements Colorful
371
398
<programlisting role="php">
372
399
<![CDATA[
373
400
<?php
401
+

374
402
interface Colorful
375
403
{
376
404
public function color(): string;
...
...
@@ -419,25 +447,26 @@ final class Suit implements UnitEnum, Colorful
419
447
<title>Enumeration static methods</title>
420
448

421
449
<para>
422
-
Enumerations may also have static methods. The use for static methods on the
423
-
enumeration itself is primarily for alternative constructors. E.g.:
450
+
Enumerations may also have static methods. The use for static methods on the
451
+
enumeration itself is primarily for alternative constructors. E.g.:
424
452
</para>
425
453

426
454
<programlisting role="php">
427
455
<![CDATA[
428
456
<?php
457
+

429
458
enum Size
430
459
{
431
460
case Small;
432
461
case Medium;
433
462
case Large;
434
463

435
-
public static function fromLength(int $cm): static
464
+
public static function fromLength(int $cm): self
436
465
{
437
466
return match(true) {
438
-
$cm < 50 => static::Small,
439
-
$cm < 100 => static::Medium,
440
-
default => static::Large,
467
+
$cm < 50 => self::Small,
468
+
$cm < 100 => self::Medium,
469
+
default => self::Large,
441
470
};
442
471
}
443
472
}
...
...
@@ -465,6 +494,7 @@ enum Size
465
494
<programlisting role="php">
466
495
<![CDATA[
467
496
<?php
497
+

468
498
enum Size
469
499
{
470
500
case Small;
...
...
@@ -483,13 +513,14 @@ enum Size
483
513

484
514
<para>Enumerations may leverage traits, which will behave the same as on classes.
485
515
The caveat is that traits <literal>use</literal>d in an enum must not contain properties.
486
-
They may only include methods and static methods. A trait with properties will
516
+
They may only include methods, static methods, and constants. A trait with properties will
487
517
result in a fatal error.
488
518
</para>
489
519

490
520
<programlisting role="php">
491
521
<![CDATA[
492
522
<?php
523
+

493
524
interface Colorful
494
525
{
495
526
public function color(): string;
...
...
@@ -544,30 +575,49 @@ enum Suit implements Colorful
544
575
<programlisting role="php">
545
576
<![CDATA[
546
577
<?php
578
+

547
579
// This is an entirely legal Enum definition.
548
580
enum Direction implements ArrayAccess
549
581
{
550
582
case Up;
551
583
case Down;
552
584

553
-
public function offsetGet($val) { ... }
554
-
public function offsetExists($val) { ... }
555
-
public function offsetSet($val) { throw new Exception(); }
556
-
public function offsetUnset($val) { throw new Exception(); }
585
+
public function offsetExists($offset): bool
586
+
{
587
+
return false;
588
+
}
589
+

590
+
public function offsetGet($offset): mixed
591
+
{
592
+
return null;
593
+
}
594
+

595
+
public function offsetSet($offset, $value): void
596
+
{
597
+
throw new Exception();
598
+
}
599
+

600
+
public function offsetUnset($offset): void
601
+
{
602
+
throw new Exception();
603
+
}
557
604
}
558
605

559
606
class Foo
560
607
{
561
608
// This is allowed.
562
-
const Bar = Direction::Down;
609
+
const DOWN = Direction::Down;
563
610

564
611
// This is disallowed, as it may not be deterministic.
565
-
const Bar = Direction::Up['short'];
612
+
const UP = Direction::Up['short'];
566
613
// Fatal error: Cannot use [] on enums in constant expression
567
614
}
568
615

569
616
// This is entirely legal, because it's not a constant expression.
570
617
$x = Direction::Up['short'];
618
+
var_dump("\$x is " . var_export($x, true));
619
+

620
+
$foo = new Foo();
571
621
?>
572
622
]]>
573
623
</programlisting>
...
...
@@ -585,8 +635,9 @@ $x = Direction::Up['short'];
585
635
<member>Constructors and Destructors are forbidden.</member>
586
636
<member>Inheritance is not supported. Enums may not extend or be extended.</member>
587
637
<member>Static or object properties are not allowed.</member>
588
-
<member>Cloning an Enum case is not supported, as cases must be singleton instances</member>
638
+
<member>Cloning an Enum case is not supported, as cases must be singleton instances.</member>
589
639
<member><link linkend="language.oop5.magic">Magic methods</link>, except for those listed below, are disallowed.</member>
640
+
<member>Enums must always be declared before they are used.</member>
590
641
</simplelist>
591
642

592
643
<para>The following object functionality is available, and behaves just as it does on any other object:</para>
...
...
@@ -598,8 +649,8 @@ $x = Direction::Up['short'];
598
649
<member>Enums may implement any number of interfaces.</member>
599
650
<member>
600
651
Enums and cases may have <link linkend="language.attributes">attributes</link> attached
601
-
to them. The <constant>TARGET_CLASS</constant> target
602
-
filter includes Enums themselves. The <constant>TARGET_CLASS_CONST</constant> target filter
652
+
to them. The <constant>TARGET_CLASS</constant> target
653
+
filter includes Enums themselves. The <constant>TARGET_CLASS_CONST</constant> target filter
603
654
includes Enum Cases.
604
655
</member>
605
656
<member>
...
...
@@ -611,21 +662,23 @@ $x = Direction::Up['short'];
611
662

612
663
<para>
613
664
The <literal>::class</literal> magic constant on an Enum type evaluates to the type
614
-
name including any namespace, exactly the same as an object. The <literal>::class</literal>
665
+
name including any namespace, exactly the same as an object. The <literal>::class</literal>
615
666
magic constant on a Case instance also evaluates to the Enum type, as it is an
616
667
instance of that type.
617
668
</para>
618
669

619
670
<para>
620
671
Additionally, enum cases may not be instantiated directly with <literal>new</literal>, nor with
621
-
<methodname>ReflectionClass::newInstanceWithoutConstructor</methodname> in reflection. Both will result in an error.
672
+
<methodname>ReflectionClass::newInstanceWithoutConstructor</methodname> in reflection. Both will result in an error.
622
673
</para>
623
674

624
675
<programlisting role="php">
625
676
<![CDATA[
626
677
<?php
678
+

627
679
$clovers = new Suit();
628
680
// Error: Cannot instantiate enum Suit
681
+

629
682
$horseshoes = (new ReflectionClass(Suit::class))->newInstanceWithoutConstructor()
630
683
// Error: Cannot instantiate enum Suit
631
684
?>
...
...
@@ -638,7 +691,7 @@ $horseshoes = (new ReflectionClass(Suit::class))->newInstanceWithoutConstructor(
638
691

639
692
<para>
640
693
Both Pure Enums and Backed Enums implement an internal interface named
641
-
<interfacename>UnitEnum</interfacename>. <literal>UnitEnum</literal> includes a static method
694
+
<interfacename>UnitEnum</interfacename>. <literal>UnitEnum</literal> includes a static method
642
695
<literal>cases()</literal>. <literal>cases()</literal> returns a packed array of
643
696
all defined Cases in the order of declaration.
644
697
</para>
...
...
@@ -646,6 +699,7 @@ $horseshoes = (new ReflectionClass(Suit::class))->newInstanceWithoutConstructor(
646
699
<programlisting role="php">
647
700
<![CDATA[
648
701
<?php
702
+

649
703
Suit::cases();
650
704
// Produces: [Suit::Hearts, Suit::Diamonds, Suit::Clubs, Suit::Spades]
651
705
?>
...
...
@@ -659,14 +713,15 @@ Suit::cases();
659
713
<title>Serialization</title>
660
714

661
715
<para>
662
-
Enumerations are serialized differently from objects. Specifically, they have a new serialization code,
663
-
<literal>"E"</literal>, that specifies the name of the enum case. The deserialization routine is then
664
-
able to use that to set a variable to the existing singleton value. That ensures that:
716
+
Enumerations are serialized differently from objects. Specifically, they have a new serialization code,
717
+
<literal>"E"</literal>, that specifies the name of the enum case. The deserialization routine is then
718
+
able to use that to set a variable to the existing singleton value. That ensures that:
665
719
</para>
666
720

667
721
<programlisting role="php">
668
722
<![CDATA[
669
723
<?php
724
+

670
725
Suit::Hearts === unserialize(serialize(Suit::Hearts));
671
726

672
727
print serialize(Suit::Hearts);
...
...
@@ -677,12 +732,12 @@ print serialize(Suit::Hearts);
677
732

678
733
<para>
679
734
On deserialization, if an enum and case cannot be found to match a serialized
680
-
value a warning will be issued and <literal>false</literal> returned.</para>
735
+
value a warning will be issued and &false; returned.</para>
681
736

682
737
<para>
683
-
If a Pure Enum is serialized to JSON, an error will be thrown. If a Backed Enum
684
-
is serialized to JSON, it will be represented by its value scalar only, in the
685
-
appropriate type. The behavior of both may be overridden by implementing
738
+
If a Pure Enum is serialized to JSON, an error will be thrown. If a Backed Enum
739
+
is serialized to JSON, it will be represented by its scalar value only, in the
740
+
appropriate type. The behavior of both may be overridden by implementing
686
741
<classname>JsonSerializable</classname>.
687
742
</para>
688
743

...
...
@@ -693,6 +748,7 @@ print serialize(Suit::Hearts);
693
748
<programlisting role="php">
694
749
<![CDATA[
695
750
<?php
751
+

696
752
enum Foo {
697
753
case Bar;
698
754
}
...
...
@@ -719,6 +775,105 @@ Baz Enum:int {
719
775
</programlisting>
720
776
</sect1>
721
777

778
+
<sect1 xml:id="language.enumerations.object-differences.inheritance">
779
+

780
+
<title>Why enums aren't extendable</title>
781
+

782
+
<simpara>
783
+
Classes have contracts on their methods:
784
+
</simpara>
785
+

786
+
<programlisting role="php">
787
+
<![CDATA[
788
+
<?php
789
+

790
+
class A {}
791
+
class B extends A {}
792
+

793
+
function foo(A $a) {}
794
+

795
+
function bar(B $b) {
796
+
foo($b);
797
+
}
798
+
?>
799
+
]]>
800
+
</programlisting>
801
+

802
+
<simpara>
803
+
This code is type-safe, as B follows the contract of A, and through the magic of
804
+
co/contra-variance, any expectation one may have of the methods will be
805
+
preserved, exceptions excepted.
806
+
</simpara>
807
+

808
+
<simpara>
809
+
Enums have contracts on their cases, not methods:
810
+
</simpara>
811
+

812
+
<programlisting role="php">
813
+
<![CDATA[
814
+
<?php
815
+

816
+
enum ErrorCode {
817
+
case SOMETHING_BROKE;
818
+
}
819
+

820
+
function quux(ErrorCode $errorCode)
821
+
{
822
+
// When written, this code appears to cover all cases
823
+
match ($errorCode) {
824
+
ErrorCode::SOMETHING_BROKE => true,
825
+
};
826
+
}
827
+

828
+
?>
829
+
]]>
830
+
</programlisting>
831
+

832
+
<simpara>
833
+
The &match; statement in the function <code>quux</code> can be static analyzed to cover
834
+
all of the cases in ErrorCode.
835
+
</simpara>
836
+

837
+
<simpara>
838
+
But imagine it was allowed to extend enums:
839
+
</simpara>
840
+

841
+

842
+
<programlisting role="php">
843
+
<![CDATA[
844
+
<?php
845
+

846
+
// Thought experiment code where enums are not final.
847
+
// Note, this won't actually work in PHP.
848
+
enum MoreErrorCode extends ErrorCode {
849
+
case PEBKAC;
850
+
}
851
+

852
+
function fot(MoreErrorCode $errorCode) {
853
+
quux($errorCode);
854
+
}
855
+

856
+
fot(MoreErrorCode::PEBKAC);
857
+

858
+
?>
859
+
]]>
860
+
</programlisting>
861
+

862
+
<simpara>
863
+
Under normal inheritance rules, a class that extends another will pass
864
+
the type check.
865
+
</simpara>
866
+

867
+
<simpara>
868
+
The problem would be that the &match; statement in <code>quux()</code> no longer covers all
869
+
the cases. Because it doesn't know about <code>MoreErrorCode::PEBKAC</code> the match will throw an exception.
870
+
</simpara>
871
+

872
+
<simpara>
873
+
Because of this enums are final and can't be extended.
874
+
</simpara>
875
+
</sect1>
876
+

722
877
<sect1 xml:id="language.enumerations.examples">
723
878
&reftitle.examples;
724
879

...
...
@@ -728,20 +883,24 @@ Baz Enum:int {
728
883
<programlisting role="php">
729
884
<![CDATA[
730
885
<?php
886
+

731
887
enum SortOrder
732
888
{
733
-
case ASC;
734
-
case DESC;
889
+
case Asc;
890
+
case Desc;
735
891
}
736
892

737
-
function query($fields, $filter, SortOrder $order = SortOrder::ASC) { ... }
893
+
function query($fields, $filter, SortOrder $order = SortOrder::Asc)
894
+
{
895
+
/* ... */
896
+
}
738
897
?>
739
898
]]>
740
899
</programlisting>
741
900
<para>
742
901
The <literal>query()</literal> function can now proceed safe in the knowledge that
743
-
<literal>$order</literal> is guaranteed to be either <literal>SortOrder::ASC</literal>
744
-
or <literal>SortOrder::DESC</literal>. Any other value would have resulted in a
902
+
<literal>$order</literal> is guaranteed to be either <literal>SortOrder::Asc</literal>
903
+
or <literal>SortOrder::Desc</literal>. Any other value would have resulted in a
745
904
<classname>TypeError</classname>, so no further error checking or testing is needed.
746
905
</para>
747
906
</example>
...
...
@@ -755,6 +914,7 @@ function query($fields, $filter, SortOrder $order = SortOrder::ASC) { ... }
755
914
<programlisting role="php">
756
915
<![CDATA[
757
916
<?php
917
+

758
918
enum UserStatus: string
759
919
{
760
920
case Pending = 'P';
...
...
@@ -765,10 +925,10 @@ enum UserStatus: string
765
925
public function label(): string
766
926
{
767
927
return match($this) {
768
-
static::Pending => 'Pending',
769
-
static::Active => 'Active',
770
-
static::Suspended => 'Suspended',
771
-
static::CanceledByUser => 'Canceled by user',
928
+
self::Pending => 'Pending',
929
+
self::Active => 'Active',
930
+
self::Suspended => 'Suspended',
931
+
self::CanceledByUser => 'Canceled by user',
772
932
};
773
933
}
774
934
}
...
...
@@ -779,7 +939,7 @@ enum UserStatus: string
779
939
<para>
780
940
In this example, a user's status may be one of, and exclusively, <literal>UserStatus::Pending</literal>,
781
941
<literal>UserStatus::Active</literal>, <literal>UserStatus::Suspended</literal>, or
782
-
<literal>UserStatus::CanceledByUser</literal>. A function can type a parameter against
942
+
<literal>UserStatus::CanceledByUser</literal>. A function can type a parameter against
783
943
<literal>UserStatus</literal> and then only accept those four values, period.
784
944
</para>
785
945

...
...
@@ -792,6 +952,7 @@ enum UserStatus: string
792
952
<programlisting role="php">
793
953
<![CDATA[
794
954
<?php
955
+

795
956
foreach (UserStatus::cases() as $case) {
796
957
printf('<option value="%s">%s</option>\n', $case->value, $case->label());
797
958
}
798
959