diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 5ed25431aba2b..dcef53702b5a2 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -812,7 +812,7 @@ void zend_register_default_exception(void) /* {{{ */ INIT_CLASS_ENTRY(ce, "Exception", default_exception_functions); zend_ce_exception = zend_register_internal_class_ex(&ce, NULL); zend_ce_exception->create_object = zend_default_exception_new; - zend_class_implements(zend_ce_exception, 1, zend_ce_throwable); + zend_class_implements(zend_ce_exception, 2, zend_ce_throwable, zend_ce_stringable); zend_declare_property_string(zend_ce_exception, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED); zend_declare_property_string(zend_ce_exception, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE); @@ -830,7 +830,7 @@ void zend_register_default_exception(void) /* {{{ */ INIT_CLASS_ENTRY(ce, "Error", default_exception_functions); zend_ce_error = zend_register_internal_class_ex(&ce, NULL); zend_ce_error->create_object = zend_default_exception_new; - zend_class_implements(zend_ce_error, 1, zend_ce_throwable); + zend_class_implements(zend_ce_error, 2, zend_ce_throwable, zend_ce_stringable); zend_declare_property_string(zend_ce_error, "message", sizeof("message")-1, "", ZEND_ACC_PROTECTED); zend_declare_property_string(zend_ce_error, "string", sizeof("string")-1, "", ZEND_ACC_PRIVATE); diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c index d2b96e6bf3903..18625a28334d2 100644 --- a/Zend/zend_interfaces.c +++ b/Zend/zend_interfaces.c @@ -28,6 +28,7 @@ ZEND_API zend_class_entry *zend_ce_iterator; ZEND_API zend_class_entry *zend_ce_arrayaccess; ZEND_API zend_class_entry *zend_ce_serializable; ZEND_API zend_class_entry *zend_ce_countable; +ZEND_API zend_class_entry *zend_ce_stringable; /* {{{ zend_call_method Only returns the returned zval if retval_ptr != NULL */ @@ -532,6 +533,13 @@ static int zend_implement_countable(zend_class_entry *interface, zend_class_entr } /* }}}*/ +/* {{{ zend_implement_stringable */ +static int zend_implement_stringable(zend_class_entry *interface, zend_class_entry *class_type) +{ + return SUCCESS; +} +/* }}}*/ + /* {{{ function tables */ static const zend_function_entry zend_funcs_aggregate[] = { ZEND_ABSTRACT_ME(iterator, getIterator, arginfo_class_IteratorAggregate_getIterator) @@ -567,6 +575,11 @@ static const zend_function_entry zend_funcs_countable[] = { ZEND_ABSTRACT_ME(Countable, count, arginfo_class_Countable_count) ZEND_FE_END }; + +static const zend_function_entry zend_funcs_stringable[] = { + ZEND_ABSTRACT_ME(Stringable, __toString, arginfo_class_Stringable___toString) + ZEND_FE_END +}; /* }}} */ /* {{{ zend_register_interfaces */ @@ -585,5 +598,7 @@ ZEND_API void zend_register_interfaces(void) REGISTER_MAGIC_INTERFACE(serializable, Serializable); REGISTER_MAGIC_INTERFACE(countable, Countable); + + REGISTER_MAGIC_INTERFACE(stringable, Stringable); } /* }}} */ diff --git a/Zend/zend_interfaces.h b/Zend/zend_interfaces.h index e7d0315ac5d00..c79495eca3f55 100644 --- a/Zend/zend_interfaces.h +++ b/Zend/zend_interfaces.h @@ -30,6 +30,7 @@ extern ZEND_API zend_class_entry *zend_ce_iterator; extern ZEND_API zend_class_entry *zend_ce_arrayaccess; extern ZEND_API zend_class_entry *zend_ce_serializable; extern ZEND_API zend_class_entry *zend_ce_countable; +extern ZEND_API zend_class_entry *zend_ce_stringable; typedef struct _zend_user_iterator { zend_object_iterator it; diff --git a/Zend/zend_interfaces.stub.php b/Zend/zend_interfaces.stub.php index 882a21e60048e..a382bafd78da3 100644 --- a/Zend/zend_interfaces.stub.php +++ b/Zend/zend_interfaces.stub.php @@ -49,3 +49,9 @@ interface Countable /** @return int */ function count(); } + +interface Stringable +{ + /** @return string */ + function __toString(); +} diff --git a/Zend/zend_interfaces_arginfo.h b/Zend/zend_interfaces_arginfo.h index fee57057afa0c..6d12c2eeacbe0 100644 --- a/Zend/zend_interfaces_arginfo.h +++ b/Zend/zend_interfaces_arginfo.h @@ -33,3 +33,5 @@ ZEND_BEGIN_ARG_INFO_EX(arginfo_class_Serializable_unserialize, 0, 0, 1) ZEND_END_ARG_INFO() #define arginfo_class_Countable_count arginfo_class_IteratorAggregate_getIterator + +#define arginfo_class_Stringable___toString arginfo_class_IteratorAggregate_getIterator diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 240ea4473c929..ec230acd6ae02 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -6643,6 +6643,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ INIT_CLASS_ENTRY(_reflection_entry, "Reflector", reflector_functions); reflector_ptr = zend_register_internal_interface(&_reflection_entry); + zend_class_implements(reflector_ptr, 1, zend_ce_stringable); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions); reflection_init_class_handlers(&_reflection_entry); @@ -6671,6 +6672,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ reflection_init_class_handlers(&_reflection_entry); reflection_type_ptr = zend_register_internal_class(&_reflection_entry); reflection_type_ptr->ce_flags |= ZEND_ACC_EXPLICIT_ABSTRACT_CLASS; + zend_class_implements(reflection_type_ptr, 1, zend_ce_stringable); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionNamedType", reflection_named_type_functions); reflection_init_class_handlers(&_reflection_entry); diff --git a/ext/reflection/reflection.stub.php b/ext/reflection/reflection.stub.php index 11bb6c64338b4..eedfdf84bd88c 100644 --- a/ext/reflection/reflection.stub.php +++ b/ext/reflection/reflection.stub.php @@ -12,7 +12,7 @@ public static function getModifierNames(int $modifiers) {} public static function export(Reflector $reflector, bool $return = false) {} } -interface Reflector +interface Reflector extends Stringable { /** @return string */ public function __toString(); @@ -532,7 +532,7 @@ public function getDefaultValueConstantName() {} public function isVariadic() {} } -abstract class ReflectionType +abstract class ReflectionType implements Stringable { final private function __clone() {} diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index a70e09fa68e12..08c120926aa9b 100644 --- a/ext/reflection/tests/ReflectionClass_toString_001.phpt +++ b/ext/reflection/tests/ReflectionClass_toString_001.phpt @@ -9,7 +9,7 @@ $rc = new ReflectionClass("ReflectionClass"); echo $rc; ?> --EXPECT-- -Class [ class ReflectionClass implements Reflector ] { +Class [ class ReflectionClass implements Reflector, Stringable ] { - Constants [3] { Constant [ public int IS_IMPLICIT_ABSTRACT ] { 16 } @@ -48,7 +48,7 @@ Class [ class ReflectionClass implements Reflector ] { } } - Method [ public method __toString ] { + Method [ public method __toString ] { - Parameters [0] { } diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 4e922e3ef0fbb..7a1a410c8ef23 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -2633,7 +2633,7 @@ PHP_MINIT_FUNCTION(simplexml) sxe.create_object = sxe_object_new; sxe_class_entry = zend_register_internal_class(&sxe); sxe_class_entry->get_iterator = php_sxe_get_iterator; - zend_class_implements(sxe_class_entry, 2, zend_ce_traversable, zend_ce_countable); + zend_class_implements(sxe_class_entry, 3, zend_ce_traversable, zend_ce_countable, zend_ce_stringable); memcpy(&sxe_object_handlers, &std_object_handlers, sizeof(zend_object_handlers)); sxe_object_handlers.offset = XtOffsetOf(php_sxe_object, zo); diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index da61c41f0e236..2deee62e47a45 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -3104,6 +3104,7 @@ PHP_MINIT_FUNCTION(spl_directory) spl_filesystem_object_handlers.free_obj = spl_filesystem_object_free_storage; spl_ce_SplFileInfo->serialize = zend_class_serialize_deny; spl_ce_SplFileInfo->unserialize = zend_class_unserialize_deny; + REGISTER_SPL_IMPLEMENTS(SplFileInfo, Stringable); REGISTER_SPL_SUB_CLASS_EX(DirectoryIterator, SplFileInfo, spl_filesystem_object_new, spl_DirectoryIterator_functions); diff --git a/ext/spl/spl_directory.h b/ext/spl/spl_directory.h index 88fbd0f052601..12527c9cfe6e9 100644 --- a/ext/spl/spl_directory.h +++ b/ext/spl/spl_directory.h @@ -20,6 +20,8 @@ #include "php.h" #include "php_spl.h" +#define spl_ce_Stringable zend_ce_stringable + extern PHPAPI zend_class_entry *spl_ce_SplFileInfo; extern PHPAPI zend_class_entry *spl_ce_DirectoryIterator; extern PHPAPI zend_class_entry *spl_ce_FilesystemIterator; diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c index 5e021ce493ea6..052d0dbbbbab9 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -3669,6 +3669,7 @@ PHP_MINIT_FUNCTION(spl_iterators) REGISTER_SPL_SUB_CLASS_EX(CachingIterator, IteratorIterator, spl_dual_it_new, spl_funcs_CachingIterator); REGISTER_SPL_IMPLEMENTS(CachingIterator, ArrayAccess); REGISTER_SPL_IMPLEMENTS(CachingIterator, Countable); + REGISTER_SPL_IMPLEMENTS(CachingIterator, Stringable); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CALL_TOSTRING", CIT_CALL_TOSTRING); REGISTER_SPL_CLASS_CONST_LONG(CachingIterator, "CATCH_GET_CHILD", CIT_CATCH_GET_CHILD); diff --git a/ext/spl/spl_iterators.h b/ext/spl/spl_iterators.h index a3b02bf8bce91..5d890bb2b90ab 100644 --- a/ext/spl/spl_iterators.h +++ b/ext/spl/spl_iterators.h @@ -27,6 +27,7 @@ #define spl_ce_ArrayAccess zend_ce_arrayaccess #define spl_ce_Serializable zend_ce_serializable #define spl_ce_Countable zend_ce_countable +#define spl_ce_Stringable zend_ce_stringable extern PHPAPI zend_class_entry *spl_ce_RecursiveIterator; extern PHPAPI zend_class_entry *spl_ce_RecursiveIteratorIterator; diff --git a/ext/standard/tests/strings/strlen.phpt b/ext/standard/tests/strings/strlen.phpt index 0db36eea22aed..f5929e62ffc19 100644 Binary files a/ext/standard/tests/strings/strlen.phpt and b/ext/standard/tests/strings/strlen.phpt differ diff --git a/ext/standard/tests/strings/strpos.phpt b/ext/standard/tests/strings/strpos.phpt index 2bc95a6c0a900..f8b6e1fe233a4 100644 Binary files a/ext/standard/tests/strings/strpos.phpt and b/ext/standard/tests/strings/strpos.phpt differ diff --git a/ext/standard/tests/strings/strstr.phpt b/ext/standard/tests/strings/strstr.phpt index 22fe2d0da93be..3613231e00443 100644 Binary files a/ext/standard/tests/strings/strstr.phpt and b/ext/standard/tests/strings/strstr.phpt differ diff --git a/ext/standard/tests/strings/ucfirst.phpt b/ext/standard/tests/strings/ucfirst.phpt index ea575f6f11e22..eb12f7ca1d531 100644 Binary files a/ext/standard/tests/strings/ucfirst.phpt and b/ext/standard/tests/strings/ucfirst.phpt differ diff --git a/ext/zend_test/test.c b/ext/zend_test/test.c index 2f21bd8158e31..467b3f25d9515 100644 --- a/ext/zend_test/test.c +++ b/ext/zend_test/test.c @@ -237,7 +237,6 @@ PHP_MINIT_FUNCTION(zend_test) zend_declare_class_constant_long(zend_test_interface, ZEND_STRL("DUMMY"), 0); INIT_CLASS_ENTRY(class_entry, "_ZendTestClass", zend_test_class_methods); zend_test_class = zend_register_internal_class(&class_entry); - zend_class_implements(zend_test_class, 1, zend_test_interface); zend_test_class->create_object = zend_test_class_new; zend_test_class->get_static_method = zend_test_class_static_method_get;