From 3b14e2c389ede4d8d3a806d311dd64bac1411336 Mon Sep 17 00:00:00 2001 From: Daniel Scherzer Date: Thu, 12 Mar 2026 16:52:59 -0700 Subject: [PATCH] [RFC] Allow __debugInfo() on enums https://wiki.php.net/rfc/debugable-enums --- Zend/tests/enum/__debugInfo.phpt | 16 -------------- .../enum/debugInfo/backed_enum_value.phpt | 21 +++++++++++++++++++ Zend/tests/enum/debugInfo/magic_method.phpt | 21 +++++++++++++++++++ Zend/tests/enum/debugInfo/missing_magic.phpt | 14 +++++++++++++ .../enum/debugInfo/param_validation.phpt | 18 ++++++++++++++++ .../enum/debugInfo/return_validation.phpt | 18 ++++++++++++++++ .../enum/debugInfo/visibility_validation.phpt | 20 ++++++++++++++++++ Zend/zend_enum.c | 3 +-- ext/standard/var.c | 2 +- 9 files changed, 114 insertions(+), 19 deletions(-) delete mode 100644 Zend/tests/enum/__debugInfo.phpt create mode 100644 Zend/tests/enum/debugInfo/backed_enum_value.phpt create mode 100644 Zend/tests/enum/debugInfo/magic_method.phpt create mode 100644 Zend/tests/enum/debugInfo/missing_magic.phpt create mode 100644 Zend/tests/enum/debugInfo/param_validation.phpt create mode 100644 Zend/tests/enum/debugInfo/return_validation.phpt create mode 100644 Zend/tests/enum/debugInfo/visibility_validation.phpt diff --git a/Zend/tests/enum/__debugInfo.phpt b/Zend/tests/enum/__debugInfo.phpt deleted file mode 100644 index 33e0f49851f9c..0000000000000 --- a/Zend/tests/enum/__debugInfo.phpt +++ /dev/null @@ -1,16 +0,0 @@ ---TEST-- -Enum __debugInfo ---FILE-- -cases(); - } -} - -?> ---EXPECTF-- -Fatal error: Enum Foo cannot include magic method __debugInfo in %s on line %d diff --git a/Zend/tests/enum/debugInfo/backed_enum_value.phpt b/Zend/tests/enum/debugInfo/backed_enum_value.phpt new file mode 100644 index 0000000000000..cb3763c56f1ef --- /dev/null +++ b/Zend/tests/enum/debugInfo/backed_enum_value.phpt @@ -0,0 +1,21 @@ +--TEST-- +Enum with __debugInfo() magic method - backed enum value accessible +--FILE-- +name . ' = ' . $this->value ]; + } +} + +var_dump(Foo::Bar); + +?> +--EXPECTF-- +object(Foo)#%d (1) { + [0]=> + string(14) "Foo::Bar = Baz" +} diff --git a/Zend/tests/enum/debugInfo/magic_method.phpt b/Zend/tests/enum/debugInfo/magic_method.phpt new file mode 100644 index 0000000000000..e01452612ac94 --- /dev/null +++ b/Zend/tests/enum/debugInfo/magic_method.phpt @@ -0,0 +1,21 @@ +--TEST-- +Enum supports __debugInfo() magic method +--FILE-- +name . ' is a case of the ' . __CLASS__ . ' enum']; + } +} + +var_dump(Foo::Bar); + +?> +--EXPECTF-- +object(Foo)#%d (1) { + [0]=> + string(29) "Bar is a case of the Foo enum" +} diff --git a/Zend/tests/enum/debugInfo/missing_magic.phpt b/Zend/tests/enum/debugInfo/missing_magic.phpt new file mode 100644 index 0000000000000..9cb5b0c69e52e --- /dev/null +++ b/Zend/tests/enum/debugInfo/missing_magic.phpt @@ -0,0 +1,14 @@ +--TEST-- +When an enum does not have __debugInfo() it is printed nicely +--FILE-- + +--EXPECT-- +enum(Foo::Bar) diff --git a/Zend/tests/enum/debugInfo/param_validation.phpt b/Zend/tests/enum/debugInfo/param_validation.phpt new file mode 100644 index 0000000000000..84c60730822e7 --- /dev/null +++ b/Zend/tests/enum/debugInfo/param_validation.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum with __debugInfo() magic method - param validation +--FILE-- + +--EXPECTF-- +Fatal error: Method Foo::__debugInfo() cannot take arguments in %s on line %d diff --git a/Zend/tests/enum/debugInfo/return_validation.phpt b/Zend/tests/enum/debugInfo/return_validation.phpt new file mode 100644 index 0000000000000..5583dcadf409a --- /dev/null +++ b/Zend/tests/enum/debugInfo/return_validation.phpt @@ -0,0 +1,18 @@ +--TEST-- +Enum with __debugInfo() magic method - return validation +--FILE-- + +--EXPECTF-- +Fatal error: Foo::__debugInfo(): Return type must be ?array when declared in %s on line %d diff --git a/Zend/tests/enum/debugInfo/visibility_validation.phpt b/Zend/tests/enum/debugInfo/visibility_validation.phpt new file mode 100644 index 0000000000000..8b31651da0110 --- /dev/null +++ b/Zend/tests/enum/debugInfo/visibility_validation.phpt @@ -0,0 +1,20 @@ +--TEST-- +Enum with __debugInfo() magic method - visibility validation +--FILE-- + +--EXPECTF-- +Warning: The magic method Foo::__debugInfo() must have public visibility in %s on line %d +object(Foo)#%d (0) { +} diff --git a/Zend/zend_enum.c b/Zend/zend_enum.c index 6e9c68810d4b4..35192732147ff 100644 --- a/Zend/zend_enum.c +++ b/Zend/zend_enum.c @@ -91,7 +91,7 @@ static void zend_verify_enum_properties(const zend_class_entry *ce) static void zend_verify_enum_magic_methods(const zend_class_entry *ce) { - // Only __get, __call and __invoke are allowed + // Only __get, __call, __debugInfo and __invoke are allowed ZEND_ENUM_DISALLOW_MAGIC_METHOD(constructor, "__construct"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(destructor, "__destruct"); @@ -101,7 +101,6 @@ static void zend_verify_enum_magic_methods(const zend_class_entry *ce) ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unset, "__unset"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__isset, "__isset"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__tostring, "__toString"); - ZEND_ENUM_DISALLOW_MAGIC_METHOD(__debugInfo, "__debugInfo"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__serialize, "__serialize"); ZEND_ENUM_DISALLOW_MAGIC_METHOD(__unserialize, "__unserialize"); diff --git a/ext/standard/var.c b/ext/standard/var.c index 8d4c592637253..d46b9f88740e6 100644 --- a/ext/standard/var.c +++ b/ext/standard/var.c @@ -168,7 +168,7 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ break; case IS_OBJECT: { zend_class_entry *ce = Z_OBJCE_P(struc); - if (ce->ce_flags & ZEND_ACC_ENUM) { + if (ce->ce_flags & ZEND_ACC_ENUM && ce->__debugInfo == NULL) { zval *case_name_zval = zend_enum_fetch_case_name(Z_OBJ_P(struc)); php_printf("%senum(%s::%s)\n", COMMON, ZSTR_VAL(ce->name), Z_STRVAL_P(case_name_zval)); return;