Skip to content

Commit 7809a95

Browse files
[RFC] Allow __toString() on enums
https://wiki.php.net/rfc/stringable-enums
1 parent 67e5d6c commit 7809a95

8 files changed

Lines changed: 122 additions & 18 deletions

Zend/tests/enum/__toString.phpt

Lines changed: 0 additions & 16 deletions
This file was deleted.
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Enum with __toString() magic method - backed enum value accessible
3+
--FILE--
4+
<?php
5+
6+
enum Foo: string {
7+
case Bar = "Baz";
8+
9+
public function __toString() {
10+
return __CLASS__ . '::' . $this->name . ' = ' . $this->value;
11+
}
12+
}
13+
14+
echo Foo::Bar;
15+
16+
?>
17+
--EXPECT--
18+
Foo::Bar = Baz
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
--TEST--
2+
Enum with __toString() magic method - Stringable interface added
3+
--FILE--
4+
<?php
5+
6+
enum Foo {
7+
case Bar;
8+
9+
public function __toString() {
10+
return $this->name . ' is a case of the ' . __CLASS__ . ' enum';
11+
}
12+
}
13+
14+
function printStringable(Stringable $s) {
15+
echo $s;
16+
}
17+
18+
var_dump(class_implements(Foo::class));
19+
printStringable(Foo::Bar);
20+
21+
?>
22+
--EXPECT--
23+
array(2) {
24+
["UnitEnum"]=>
25+
string(8) "UnitEnum"
26+
["Stringable"]=>
27+
string(10) "Stringable"
28+
}
29+
Bar is a case of the Foo enum
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Enum supports __toString() magic method
3+
--FILE--
4+
<?php
5+
6+
enum Foo {
7+
case Bar;
8+
9+
public function __toString() {
10+
return $this->name . ' is a case of the ' . __CLASS__ . ' enum';
11+
}
12+
}
13+
14+
echo Foo::Bar;
15+
16+
?>
17+
--EXPECT--
18+
Bar is a case of the Foo enum
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Enum with __toString() magic method - param validation
3+
--FILE--
4+
<?php
5+
6+
enum Foo {
7+
case Bar;
8+
9+
public function __toString(mixed $arg): string {
10+
return '';
11+
}
12+
}
13+
14+
echo Foo::Bar;
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Method Foo::__toString() cannot take arguments in %s on line %d
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
--TEST--
2+
Enum with __toString() magic method - return validation
3+
--FILE--
4+
<?php
5+
6+
enum Foo {
7+
case Bar;
8+
9+
public function __toString(): int {
10+
return 5;
11+
}
12+
}
13+
14+
echo Foo::Bar;
15+
16+
?>
17+
--EXPECTF--
18+
Fatal error: Foo::__toString(): Return type must be string when declared in %s on line %d
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
--TEST--
2+
Enum with __toString() magic method - visibility validation
3+
--FILE--
4+
<?php
5+
6+
enum Foo {
7+
case Bar;
8+
9+
private function __toString(): string {
10+
return '';
11+
}
12+
}
13+
14+
echo Foo::Bar;
15+
16+
?>
17+
--EXPECTF--
18+
Warning: The magic method Foo::__toString() must have public visibility in %s on line %d
19+
20+
Fatal error: Access level to Foo::__toString() must be public (as in class Stringable) in %s on line %d

Zend/zend_enum.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -80,7 +80,7 @@ static void zend_verify_enum_properties(const zend_class_entry *ce)
8080

8181
static void zend_verify_enum_magic_methods(const zend_class_entry *ce)
8282
{
83-
// Only __get, __call and __invoke are allowed
83+
// Only __get, __call, __toString, and __invoke are allowed
8484

8585
ZEND_ENUM_DISALLOW_MAGIC_METHOD(constructor, "__construct");
8686
ZEND_ENUM_DISALLOW_MAGIC_METHOD(destructor, "__destruct");
@@ -89,7 +89,6 @@ static void zend_verify_enum_magic_methods(const zend_class_entry *ce)
8989
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__set, "__set");
9090
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unset, "__unset");
9191
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__isset, "__isset");
92-
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__tostring, "__toString");
9392
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__debugInfo, "__debugInfo");
9493
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__serialize, "__serialize");
9594
ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unserialize, "__unserialize");

0 commit comments

Comments
 (0)