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..2bf56eb3a59e5 --- /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); + +?> +--EXPECT-- +enum(Foo::Bar) (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..4c5963f73b26e --- /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); + +?> +--EXPECT-- +enum(Foo::Bar) (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..97e2f2c7456b6 --- /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 +enum(Foo::Bar) (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..309ea3575fc58 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; @@ -182,11 +182,16 @@ PHPAPI void php_var_dump(zval *struc, int level) /* {{{ */ ZEND_GUARD_OR_GC_PROTECT_RECURSION(guard, DEBUG, zobj); myht = zend_get_properties_for(struc, ZEND_PROP_PURPOSE_DEBUG); - class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); - const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); + if (ce->ce_flags & ZEND_ACC_ENUM) { + zval *case_name_zval = zend_enum_fetch_case_name(Z_OBJ_P(struc)); + php_printf("%senum(%s::%s) (%d) {\n", COMMON, ZSTR_VAL(ce->name), Z_STRVAL_P(case_name_zval), myht ? zend_array_count(myht) : 0); + } else { + class_name = Z_OBJ_HANDLER_P(struc, get_class_name)(Z_OBJ_P(struc)); + const char *prefix = php_var_dump_object_prefix(Z_OBJ_P(struc)); - php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); - zend_string_release_ex(class_name, 0); + php_printf("%s%sobject(%s)#%d (%d) {\n", COMMON, prefix, ZSTR_VAL(class_name), Z_OBJ_HANDLE_P(struc), myht ? zend_array_count(myht) : 0); + zend_string_release_ex(class_name, 0); + } if (myht) { zend_ulong num;