diff --git a/Zend/tests/list_keyed_evaluation_order.inc b/Zend/tests/list_keyed_evaluation_order.inc index d4ee778b634ac..577a19a83803a 100644 --- a/Zend/tests/list_keyed_evaluation_order.inc +++ b/Zend/tests/list_keyed_evaluation_order.inc @@ -2,7 +2,7 @@ // Observer objects for the Zend/tests/list_keyed_evaluation_order.* tests -class Stringable +class StringCapable { private $name; public function __construct(string $name) { diff --git a/Zend/tests/list_keyed_evaluation_order.phpt b/Zend/tests/list_keyed_evaluation_order.phpt index 0f0652b6a9b43..3c5fb7e8770c1 100644 --- a/Zend/tests/list_keyed_evaluation_order.phpt +++ b/Zend/tests/list_keyed_evaluation_order.phpt @@ -5,8 +5,8 @@ list() with keys, evaluation order require_once "list_keyed_evaluation_order.inc"; -$a = new Stringable("A"); -$c = new Stringable("C"); +$a = new StringCapable("A"); +$c = new StringCapable("C"); $e = new IndexableRetrievable("E", new Indexable(["A" => "value for offset A", "C" => "value for offset C"])); diff --git a/Zend/tests/list_keyed_evaluation_order_nested.phpt b/Zend/tests/list_keyed_evaluation_order_nested.phpt index 8a7725d4eaaae..496deefbb9879 100644 --- a/Zend/tests/list_keyed_evaluation_order_nested.phpt +++ b/Zend/tests/list_keyed_evaluation_order_nested.phpt @@ -5,11 +5,11 @@ list() with keys, evaluation order: nested require_once "list_keyed_evaluation_order.inc"; -$a = new Stringable("A"); -$c = new Stringable("C"); -$f = new Stringable("F"); -$g = new Stringable("G"); -$i = new Stringable("I"); +$a = new StringCapable("A"); +$c = new StringCapable("C"); +$f = new StringCapable("F"); +$g = new StringCapable("G"); +$i = new StringCapable("I"); $k = new IndexableRetrievable("K", new Indexable([ "A" => "offset value for A", diff --git a/Zend/tests/type_declarations/scalar_basic.phpt b/Zend/tests/type_declarations/scalar_basic.phpt index 1253f48c16b01..78d29591775a4 100644 --- a/Zend/tests/type_declarations/scalar_basic.phpt +++ b/Zend/tests/type_declarations/scalar_basic.phpt @@ -19,7 +19,7 @@ $functions = [ 'bool' => function (bool $b) { return $b; } ]; -class Stringable { +class StringCapable { public function __toString() { return "foobar"; } @@ -40,7 +40,7 @@ $values = [ NULL, [], new StdClass, - new Stringable, + new StringCapable, fopen("data:text/plain,foobar", "r") ]; @@ -106,7 +106,7 @@ int(0) } *** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d -*** Trying object(Stringable)#%s (0) { +*** Trying object(StringCapable)#%s (0) { } *** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d @@ -160,7 +160,7 @@ float(0) } *** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d -*** Trying object(Stringable)#%s (0) { +*** Trying object(StringCapable)#%s (0) { } *** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d @@ -213,7 +213,7 @@ string(0) "" } *** Caught Argument 1 passed to {closure}() must be of the type string, object given, called in %s on line %d -*** Trying object(Stringable)#%s (0) { +*** Trying object(StringCapable)#%s (0) { } string(6) "foobar" @@ -266,7 +266,7 @@ bool(false) } *** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d -*** Trying object(Stringable)#%s (0) { +*** Trying object(StringCapable)#%s (0) { } *** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d diff --git a/Zend/tests/type_declarations/scalar_return_basic.phpt b/Zend/tests/type_declarations/scalar_return_basic.phpt index c69196269f06c..a568d2c3c016e 100644 --- a/Zend/tests/type_declarations/scalar_return_basic.phpt +++ b/Zend/tests/type_declarations/scalar_return_basic.phpt @@ -21,7 +21,7 @@ $functions = [ 'bool' => function ($b): bool { return $b; } ]; -class Stringable { +class StringCapable { public function __toString() { return "foobar"; } @@ -42,7 +42,7 @@ $values = [ NULL, [], new StdClass, - new Stringable, + new StringCapable, fopen("data:text/plain,foobar", "r") ]; @@ -94,7 +94,7 @@ int(0) *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type int, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } *** Caught Return value of {closure}() must be of the type int, object returned in %s on line %d *** Trying resource(5) of type (stream) @@ -132,7 +132,7 @@ float(0) *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } *** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d *** Trying resource(5) of type (stream) @@ -169,7 +169,7 @@ string(0) "" *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type string, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } string(6) "foobar" *** Trying resource(5) of type (stream) @@ -206,7 +206,7 @@ bool(false) *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type bool, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } *** Caught Return value of {closure}() must be of the type bool, object returned in %s on line %d *** Trying resource(5) of type (stream) diff --git a/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt b/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt index 6f2ff11eb211c..ac64db7b841fb 100644 --- a/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt +++ b/Zend/tests/type_declarations/scalar_return_basic_64bit.phpt @@ -21,7 +21,7 @@ $functions = [ 'bool' => function ($b): bool { return $b; } ]; -class Stringable { +class StringCapable { public function __toString() { return "foobar"; } @@ -42,7 +42,7 @@ $values = [ NULL, [], new StdClass, - new Stringable, + new StringCapable, fopen("data:text/plain,foobar", "r") ]; @@ -94,7 +94,7 @@ int(0) *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type int, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } *** Caught Return value of {closure}() must be of the type int, object returned in %s on line %d *** Trying resource(5) of type (stream) @@ -132,7 +132,7 @@ float(0) *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } *** Caught Return value of {closure}() must be of the type float, object returned in %s on line %d *** Trying resource(5) of type (stream) @@ -169,7 +169,7 @@ string(0) "" *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type string, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } string(6) "foobar" *** Trying resource(5) of type (stream) @@ -206,7 +206,7 @@ bool(false) *** Trying object(stdClass)#6 (0) { } *** Caught Return value of {closure}() must be of the type bool, object returned in %s on line %d -*** Trying object(Stringable)#7 (0) { +*** Trying object(StringCapable)#7 (0) { } *** Caught Return value of {closure}() must be of the type bool, object returned in %s on line %d *** Trying resource(5) of type (stream) diff --git a/Zend/tests/type_declarations/scalar_strict.phpt b/Zend/tests/type_declarations/scalar_strict.phpt index 78b404f9f1651..ecc53860cdf32 100644 --- a/Zend/tests/type_declarations/scalar_strict.phpt +++ b/Zend/tests/type_declarations/scalar_strict.phpt @@ -13,7 +13,7 @@ $functions = [ 'bool' => function (bool $b) { return $b; } ]; -class Stringable { +class StringCapable { public function __toString() { return "foobar"; } @@ -34,7 +34,7 @@ $values = [ NULL, [], new StdClass, - new Stringable, + new StringCapable, fopen("data:text/plain,foobar", "r") ]; @@ -100,7 +100,7 @@ int(2147483647) } *** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d @@ -153,7 +153,7 @@ float(NAN) } *** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d @@ -206,7 +206,7 @@ string(0) "" } *** Caught Argument 1 passed to {closure}() must be of the type string, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type string, object given, called in %s on line %d @@ -259,7 +259,7 @@ bool(false) } *** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d diff --git a/Zend/tests/type_declarations/scalar_strict_64bit.phpt b/Zend/tests/type_declarations/scalar_strict_64bit.phpt index d6d38213a4e36..e5eb857c5d935 100644 --- a/Zend/tests/type_declarations/scalar_strict_64bit.phpt +++ b/Zend/tests/type_declarations/scalar_strict_64bit.phpt @@ -13,7 +13,7 @@ $functions = [ 'bool' => function (bool $b) { return $b; } ]; -class Stringable { +class StringCapable { public function __toString() { return "foobar"; } @@ -34,7 +34,7 @@ $values = [ NULL, [], new StdClass, - new Stringable, + new StringCapable, fopen("data:text/plain,foobar", "r") ]; @@ -100,7 +100,7 @@ int(9223372036854775807) } *** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type int, object given, called in %s on line %d @@ -153,7 +153,7 @@ float(NAN) } *** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type float, object given, called in %s on line %d @@ -206,7 +206,7 @@ string(0) "" } *** Caught Argument 1 passed to {closure}() must be of the type string, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type string, object given, called in %s on line %d @@ -259,7 +259,7 @@ bool(false) } *** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d -*** Trying object(Stringable)#6 (0) { +*** Trying object(StringCapable)#6 (0) { } *** Caught Argument 1 passed to {closure}() must be of the type bool, object given, called in %s on line %d diff --git a/Zend/zend_exceptions.c b/Zend/zend_exceptions.c index 5ed25431aba2b..79f5ecffecdcb 100644 --- a/Zend/zend_exceptions.c +++ b/Zend/zend_exceptions.c @@ -754,6 +754,20 @@ ZEND_METHOD(exception, __toString) } /* }}} */ +/* {{{ proto string Exception|Error::toString() + Obtain the string representation of the Exception object */ +ZEND_METHOD(exception, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /** {{{ Throwable method definition */ static const zend_function_entry zend_funcs_throwable[] = { ZEND_ABSTRACT_ME(throwable, getMessage, arginfo_class_Throwable_getMessage) @@ -790,6 +804,7 @@ static const zend_function_entry default_exception_functions[] = { ZEND_ME(exception, getPrevious, arginfo_class_Exception_getPrevious, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, getTraceAsString, arginfo_class_Exception_getTraceAsString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(exception, __toString, arginfo_class_Exception___toString, 0) + ZEND_ME(exception, toString, arginfo_class_Exception_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_FE_END }; @@ -812,7 +827,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 +845,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_exceptions.stub.php b/Zend/zend_exceptions.stub.php index 96d581caf97e4..ff0ae981dfabd 100644 --- a/Zend/zend_exceptions.stub.php +++ b/Zend/zend_exceptions.stub.php @@ -1,6 +1,6 @@ name)); } } + if (zend_class_implements_interface(ce, zend_ce_stringable)) { + zend_call_method_with_0_params(readobj, NULL, NULL, "tostring", &retval); + ZVAL_COPY_VALUE(writeobj, &retval); + return SUCCESS; + } return FAILURE; case _IS_BOOL: ZVAL_TRUE(writeobj); diff --git a/ext/filter/filter.c b/ext/filter/filter.c index 996308a4181de..48c148b152a07 100644 --- a/ext/filter/filter.c +++ b/ext/filter/filter.c @@ -345,7 +345,7 @@ static void php_zval_filter(zval *value, zend_long filter, zend_long flags, zval zend_class_entry *ce; ce = Z_OBJCE_P(value); - if (!ce->__tostring) { + if (!ce->__tostring && !zend_class_implements_interface(ce, zend_ce_stringable)) { zval_ptr_dtor(value); /* #67167: doesn't return null on failure for objects */ if (flags & FILTER_NULL_ON_FAILURE) { diff --git a/ext/filter/php_filter.h b/ext/filter/php_filter.h index 2a923ab953f96..4fd401cdc2575 100644 --- a/ext/filter/php_filter.h +++ b/ext/filter/php_filter.h @@ -26,6 +26,7 @@ #include "ext/standard/php_string.h" #include "ext/standard/html.h" #include "php_variables.h" +#include "zend_interfaces.h" extern zend_module_entry filter_module_entry; #define phpext_filter_ptr &filter_module_entry diff --git a/ext/reflection/php_reflection.c b/ext/reflection/php_reflection.c index 240ea4473c929..d930903482443 100644 --- a/ext/reflection/php_reflection.c +++ b/ext/reflection/php_reflection.c @@ -1553,6 +1553,20 @@ ZEND_METHOD(reflection_function, __toString) } /* }}} */ +/* {{{ proto string ReflectionFunction::toString() + Returns a string representation */ +ZEND_METHOD(reflection_function, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionFunction::getName() Returns this function's name */ ZEND_METHOD(reflection_function, getName) @@ -2458,6 +2472,20 @@ ZEND_METHOD(reflection_parameter, __toString) /* }}} */ +/* {{{ proto string ReflectionParameter::toString() + Returns a string representation */ +ZEND_METHOD(reflection_parameter, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionParameter::getName() Returns this parameters's name */ ZEND_METHOD(reflection_parameter, getName) @@ -2889,6 +2917,20 @@ ZEND_METHOD(reflection_type, __toString) } /* }}} */ +/* {{{ proto string ReflectionType::toString() + Returns a string representation */ +ZEND_METHOD(reflection_type, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionNamedType::getName() Return the name of the type */ ZEND_METHOD(reflection_named_type, getName) @@ -3119,6 +3161,20 @@ ZEND_METHOD(reflection_method, __toString) } /* }}} */ +/* {{{ proto string ReflectionMethod::toString() + Returns a string representation */ +ZEND_METHOD(reflection_method, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public mixed ReflectionMethod::getClosure([mixed object]) Invokes the function */ ZEND_METHOD(reflection_method, getClosure) @@ -3648,6 +3704,20 @@ ZEND_METHOD(reflection_class_constant, __toString) } /* }}} */ +/* {{{ proto string ReflectionClassConstant::toString() + Returns a string representation */ +ZEND_METHOD(reflection_class_constant, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionClassConstant::getName() Returns the constant' name */ ZEND_METHOD(reflection_class_constant, getName) @@ -4007,6 +4077,20 @@ ZEND_METHOD(reflection_class, __toString) } /* }}} */ +/* {{{ proto string ReflectionClass::toString() + Returns a string representation */ +ZEND_METHOD(reflection_class, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionClass::getName() Returns the class' name */ ZEND_METHOD(reflection_class, getName) @@ -5388,6 +5472,20 @@ ZEND_METHOD(reflection_property, __toString) } /* }}} */ +/* {{{ proto string ReflectionProperty::toString() + Returns a string representation */ +ZEND_METHOD(reflection_property, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionProperty::getName() Returns the class' name */ ZEND_METHOD(reflection_property, getName) @@ -5774,6 +5872,20 @@ ZEND_METHOD(reflection_extension, __toString) } /* }}} */ +/* {{{ proto string ReflectionExtension::toString() + Returns a string representation */ +ZEND_METHOD(reflection_extension, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionExtension::getName() Returns this extension's name */ ZEND_METHOD(reflection_extension, getName) @@ -6125,6 +6237,20 @@ ZEND_METHOD(reflection_zend_extension, __toString) } /* }}} */ +/* {{{ proto string ReflectionZendExtension::toString() + Returns a string representation */ +ZEND_METHOD(reflection_zend_extension, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto public string ReflectionZendExtension::getName() Returns the name of this Zend extension */ ZEND_METHOD(reflection_zend_extension, getName) @@ -6365,6 +6491,7 @@ static const zend_function_entry reflection_function_abstract_functions[] = { static const zend_function_entry reflection_function_functions[] = { ZEND_ME(reflection_function, __construct, arginfo_class_ReflectionFunction___construct, 0) ZEND_ME(reflection_function, __toString, arginfo_class_ReflectionFunction___toString, 0) + ZEND_ME(reflection_function, toString, arginfo_class_ReflectionFunction_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_DEP_ME(reflection_function, export, arginfo_class_ReflectionFunction_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_function, isDisabled, arginfo_class_ReflectionFunction_isDisabled, 0) ZEND_ME(reflection_function, invoke, arginfo_class_ReflectionFunction_invoke, 0) @@ -6388,6 +6515,7 @@ static const zend_function_entry reflection_method_functions[] = { ZEND_DEP_ME(reflection_method, export, arginfo_class_ReflectionMethod_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_method, __construct, arginfo_class_ReflectionMethod___construct, 0) ZEND_ME(reflection_method, __toString, arginfo_class_ReflectionMethod___toString, 0) + ZEND_ME(reflection_method, toString, arginfo_class_ReflectionMethod_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_method, isPublic, arginfo_class_ReflectionMethod_isPublic, 0) ZEND_ME(reflection_method, isPrivate, arginfo_class_ReflectionMethod_isPrivate, 0) ZEND_ME(reflection_method, isProtected, arginfo_class_ReflectionMethod_isProtected, 0) @@ -6411,6 +6539,7 @@ static const zend_function_entry reflection_class_functions[] = { ZEND_DEP_ME(reflection_class, export, arginfo_class_ReflectionClass_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_class, __construct, arginfo_class_ReflectionClass___construct, 0) ZEND_ME(reflection_class, __toString, arginfo_class_ReflectionClass___toString, 0) + ZEND_ME(reflection_class, toString, arginfo_class_ReflectionClass_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_class, getName, arginfo_class_ReflectionClass_getName, 0) ZEND_ME(reflection_class, isInternal, arginfo_class_ReflectionClass_isInternal, 0) ZEND_ME(reflection_class, isUserDefined, arginfo_class_ReflectionClass_isUserDefined, 0) @@ -6475,6 +6604,7 @@ static const zend_function_entry reflection_property_functions[] = { ZEND_DEP_ME(reflection_property, export, arginfo_class_ReflectionProperty_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_property, __construct, arginfo_class_ReflectionProperty___construct, 0) ZEND_ME(reflection_property, __toString, arginfo_class_ReflectionProperty___toString, 0) + ZEND_ME(reflection_property, toString, arginfo_class_ReflectionProperty_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_property, getName, arginfo_class_ReflectionProperty_getName, 0) ZEND_ME(reflection_property, getValue, arginfo_class_ReflectionProperty_getValue, 0) ZEND_ME(reflection_property, setValue, arginfo_class_ReflectionProperty_setValue, 0) @@ -6498,6 +6628,7 @@ static const zend_function_entry reflection_class_constant_functions[] = { ZEND_DEP_ME(reflection_class_constant, export, arginfo_class_ReflectionClassConstant_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_class_constant, __construct, arginfo_class_ReflectionClassConstant___construct, 0) ZEND_ME(reflection_class_constant, __toString, arginfo_class_ReflectionClassConstant___toString, 0) + ZEND_ME(reflection_class_constant, toString, arginfo_class_ReflectionClassConstant_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_class_constant, getName, arginfo_class_ReflectionClassConstant_getName, 0) ZEND_ME(reflection_class_constant, getValue, arginfo_class_ReflectionClassConstant_getValue, 0) ZEND_ME(reflection_class_constant, isPublic, arginfo_class_ReflectionClassConstant_isPublic, 0) @@ -6514,6 +6645,7 @@ static const zend_function_entry reflection_parameter_functions[] = { ZEND_DEP_ME(reflection_parameter, export, arginfo_class_ReflectionParameter_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_parameter, __construct, arginfo_class_ReflectionParameter___construct, 0) ZEND_ME(reflection_parameter, __toString, arginfo_class_ReflectionParameter___toString, 0) + ZEND_ME(reflection_parameter, toString, arginfo_class_ReflectionParameter_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_parameter, getName, arginfo_class_ReflectionParameter_getName, 0) ZEND_ME(reflection_parameter, isPassedByReference, arginfo_class_ReflectionParameter_isPassedByReference, 0) ZEND_ME(reflection_parameter, canBePassedByValue, arginfo_class_ReflectionParameter_canBePassedByValue, 0) @@ -6539,6 +6671,7 @@ static const zend_function_entry reflection_type_functions[] = { ZEND_ME(reflection, __clone, arginfo_class_ReflectionType___clone, ZEND_ACC_PRIVATE|ZEND_ACC_FINAL) ZEND_ME(reflection_type, allowsNull, arginfo_class_ReflectionType_allowsNull, 0) ZEND_ME(reflection_type, __toString, arginfo_class_ReflectionType___toString, 0) + ZEND_ME(reflection_type, toString, arginfo_class_ReflectionType_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; @@ -6558,6 +6691,7 @@ static const zend_function_entry reflection_extension_functions[] = { ZEND_DEP_ME(reflection_extension, export, arginfo_class_ReflectionExtension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_extension, __construct, arginfo_class_ReflectionExtension___construct, 0) ZEND_ME(reflection_extension, __toString, arginfo_class_ReflectionExtension___toString, 0) + ZEND_ME(reflection_extension, toString, arginfo_class_ReflectionExtension_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_extension, getName, arginfo_class_ReflectionExtension_getName, 0) ZEND_ME(reflection_extension, getVersion, arginfo_class_ReflectionExtension_getVersion, 0) ZEND_ME(reflection_extension, getFunctions, arginfo_class_ReflectionExtension_getFunctions, 0) @@ -6577,6 +6711,7 @@ static const zend_function_entry reflection_zend_extension_functions[] = { ZEND_DEP_ME(reflection_zend_extension, export, arginfo_class_ReflectionZendExtension_export, ZEND_ACC_STATIC|ZEND_ACC_PUBLIC) ZEND_ME(reflection_zend_extension, __construct, arginfo_class_ReflectionZendExtension___construct, 0) ZEND_ME(reflection_zend_extension, __toString, arginfo_class_ReflectionZendExtension___toString, 0) + ZEND_ME(reflection_zend_extension, toString, arginfo_class_ReflectionZendExtension_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) ZEND_ME(reflection_zend_extension, getName, arginfo_class_ReflectionZendExtension_getName, 0) ZEND_ME(reflection_zend_extension, getVersion, arginfo_class_ReflectionZendExtension_getVersion, 0) ZEND_ME(reflection_zend_extension, getAuthor, arginfo_class_ReflectionZendExtension_getAuthor, 0) @@ -6647,7 +6782,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunctionAbstract", reflection_function_abstract_functions); reflection_init_class_handlers(&_reflection_entry); reflection_function_abstract_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_function_abstract_ptr, 1, reflector_ptr); + zend_class_implements(reflection_function_abstract_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_function_abstract_ptr, "name", sizeof("name")-1, "", ZEND_ACC_ABSTRACT); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionFunction", reflection_function_functions); @@ -6664,13 +6799,14 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionParameter", reflection_parameter_functions); reflection_init_class_handlers(&_reflection_entry); reflection_parameter_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_parameter_ptr, 1, reflector_ptr); + zend_class_implements(reflection_parameter_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_parameter_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionType", reflection_type_functions); 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); @@ -6696,7 +6832,7 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClass", reflection_class_functions); reflection_init_class_handlers(&_reflection_entry); reflection_class_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_class_ptr, 1, reflector_ptr); + zend_class_implements(reflection_class_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_class_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); /* IS_IMPLICIT_ABSTRACT is not longer used */ @@ -6711,14 +6847,14 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionProperty", reflection_property_functions); reflection_init_class_handlers(&_reflection_entry); reflection_property_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_property_ptr, 1, reflector_ptr); + zend_class_implements(reflection_property_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_property_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_property_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionClassConstant", reflection_class_constant_functions); reflection_init_class_handlers(&_reflection_entry); reflection_class_constant_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_class_constant_ptr, 1, reflector_ptr); + zend_class_implements(reflection_class_constant_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_class_constant_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); zend_declare_property_string(reflection_class_constant_ptr, "class", sizeof("class")-1, "", ZEND_ACC_PUBLIC); @@ -6730,13 +6866,13 @@ PHP_MINIT_FUNCTION(reflection) /* {{{ */ INIT_CLASS_ENTRY(_reflection_entry, "ReflectionExtension", reflection_extension_functions); reflection_init_class_handlers(&_reflection_entry); reflection_extension_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_extension_ptr, 1, reflector_ptr); + zend_class_implements(reflection_extension_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionZendExtension", reflection_zend_extension_functions); reflection_init_class_handlers(&_reflection_entry); reflection_zend_extension_ptr = zend_register_internal_class(&_reflection_entry); - zend_class_implements(reflection_zend_extension_ptr, 1, reflector_ptr); + zend_class_implements(reflection_zend_extension_ptr, 2, reflector_ptr, zend_ce_stringable); zend_declare_property_string(reflection_zend_extension_ptr, "name", sizeof("name")-1, "", ZEND_ACC_PUBLIC); INIT_CLASS_ENTRY(_reflection_entry, "ReflectionReference", reflection_reference_functions); diff --git a/ext/reflection/reflection.stub.php b/ext/reflection/reflection.stub.php index 11bb6c64338b4..1a78aa91d3eb0 100644 --- a/ext/reflection/reflection.stub.php +++ b/ext/reflection/reflection.stub.php @@ -18,7 +18,7 @@ interface Reflector public function __toString(); } -abstract class ReflectionFunctionAbstract implements Reflector +abstract class ReflectionFunctionAbstract implements Reflector, Stringable { final private function __clone() {} @@ -106,6 +106,8 @@ public function __construct($name) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + public static function export($name, bool $return = false) {} /** @return bool */ @@ -150,6 +152,8 @@ public function __construct($class_or_method, string $name = UNKNOWN) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + public static function export($class, $name, bool $return = false) {} /** @return bool */ @@ -196,7 +200,7 @@ public function getPrototype() {} public function setAccessible(bool $visible) {} } -class ReflectionClass implements Reflector +class ReflectionClass implements Reflector, Stringable { final private function __clone() {} @@ -208,6 +212,8 @@ public function __construct($argument) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return string|false */ public function getName() {} @@ -370,7 +376,7 @@ public function __construct(object $argument) {} public static function export($argument, bool $return = false) {} } -class ReflectionProperty implements Reflector +class ReflectionProperty implements Reflector, Stringable { final private function __clone() {} @@ -382,6 +388,8 @@ public function __construct($class, string $name) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return string|false */ public function getName() {} @@ -427,7 +435,7 @@ public function getType() {} public function hasType() {} } -class ReflectionClassConstant implements Reflector +class ReflectionClassConstant implements Reflector, Stringable { final private function __clone() {} @@ -439,6 +447,8 @@ public function __construct($class, string $name) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return string|false */ public function getName() {} @@ -463,7 +473,7 @@ public function getDeclaringClass() {} public function getDocComment() {} } -class ReflectionParameter implements Reflector +class ReflectionParameter implements Reflector, Stringable { final private function __clone() {} @@ -478,6 +488,8 @@ public function __construct($function, $parameter) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return string|false */ public function getName() {} @@ -532,7 +544,7 @@ public function getDefaultValueConstantName() {} public function isVariadic() {} } -abstract class ReflectionType +abstract class ReflectionType implements Stringable { final private function __clone() {} @@ -541,6 +553,8 @@ public function allowsNull() {} /** @return string */ public function __toString() {} + + final public function toString(): string {} } class ReflectionNamedType extends ReflectionType @@ -557,7 +571,7 @@ class ReflectionUnionType extends ReflectionType public function getTypes(): array {} } -class ReflectionExtension implements Reflector +class ReflectionExtension implements Reflector, Stringable { final private function __clone() {} @@ -568,6 +582,8 @@ public function __construct(string $name) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return string|false */ public function getName() {} @@ -602,7 +618,7 @@ public function isPersistent() {} public function isTemporary() {} } -class ReflectionZendExtension implements Reflector +class ReflectionZendExtension implements Reflector, Stringable { final private function __clone() {} @@ -613,6 +629,8 @@ public function __construct(string $name) {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return string */ public function getName() {} diff --git a/ext/reflection/reflection_arginfo.h b/ext/reflection/reflection_arginfo.h index 078a793c9b6cf..ec81a4ff42397 100644 --- a/ext/reflection/reflection_arginfo.h +++ b/ext/reflection/reflection_arginfo.h @@ -70,6 +70,9 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionFunction___toString arginfo_class_Reflector___toString +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_ReflectionFunction_toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionFunction_export, 0, 0, 1) ZEND_ARG_INFO(0, name) ZEND_ARG_TYPE_INFO(0, return, _IS_BOOL, 0) @@ -112,6 +115,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionMethod___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionMethod_toString arginfo_class_ReflectionFunction_toString + ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionMethod_export, 0, 0, 2) ZEND_ARG_INFO(0, class) ZEND_ARG_INFO(0, name) @@ -171,6 +176,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClass___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionClass_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionClass_getName arginfo_class_Reflector___toString #define arginfo_class_ReflectionClass_isInternal arginfo_class_Reflector___toString @@ -306,6 +313,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionProperty___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionProperty_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionProperty_getName arginfo_class_Reflector___toString ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ReflectionProperty_getValue, 0, 0, 0) @@ -351,6 +360,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionClassConstant___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionClassConstant_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionClassConstant_getName arginfo_class_Reflector___toString #define arginfo_class_ReflectionClassConstant_getValue arginfo_class_Reflector___toString @@ -382,6 +393,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionParameter___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionParameter_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionParameter_getName arginfo_class_Reflector___toString #define arginfo_class_ReflectionParameter_isPassedByReference arginfo_class_Reflector___toString @@ -424,6 +437,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionType___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionType_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionNamedType_getName arginfo_class_Reflector___toString #define arginfo_class_ReflectionNamedType_isBuiltin arginfo_class_Reflector___toString @@ -439,6 +454,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionExtension___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionExtension_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionExtension_getName arginfo_class_Reflector___toString #define arginfo_class_ReflectionExtension_getVersion arginfo_class_Reflector___toString @@ -469,6 +486,8 @@ ZEND_END_ARG_INFO() #define arginfo_class_ReflectionZendExtension___toString arginfo_class_Reflector___toString +#define arginfo_class_ReflectionZendExtension_toString arginfo_class_ReflectionFunction_toString + #define arginfo_class_ReflectionZendExtension_getName arginfo_class_Reflector___toString #define arginfo_class_ReflectionZendExtension_getVersion arginfo_class_Reflector___toString diff --git a/ext/reflection/tests/ReflectionClass_toString_001.phpt b/ext/reflection/tests/ReflectionClass_toString_001.phpt index a70e09fa68e12..fe95128d9fd5d 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 } @@ -34,7 +34,7 @@ Class [ class ReflectionClass implements Reflector ] { Property [ public $name ] } - - Methods [53] { + - Methods [54] { Method [ final private method __clone ] { - Parameters [0] { @@ -54,6 +54,13 @@ Class [ class ReflectionClass implements Reflector ] { } } + Method [ final public method toString ] { + + - Parameters [0] { + } + - Return [ string ] + } + Method [ public method getName ] { - Parameters [0] { diff --git a/ext/simplexml/simplexml.c b/ext/simplexml/simplexml.c index 4e922e3ef0fbb..3fabaa96c957a 100644 --- a/ext/simplexml/simplexml.c +++ b/ext/simplexml/simplexml.c @@ -1954,6 +1954,20 @@ SXE_METHOD(__toString) } /* }}} */ +/* {{{ proto object SimpleXMLElement::toString() + Returns the string content */ +SXE_METHOD(toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + static int php_sxe_count_elements_helper(php_sxe_object *sxe, zend_long *count) /* {{{ */ { xmlNodePtr node; @@ -2618,6 +2632,7 @@ static const zend_function_entry sxe_functions[] = { /* {{{ */ SXE_ME(addChild, arginfo_class_SimpleXMLElement_addChild, ZEND_ACC_PUBLIC) SXE_ME(addAttribute, arginfo_class_SimpleXMLElement_addAttribute, ZEND_ACC_PUBLIC) SXE_ME(__toString, arginfo_class_SimpleXMLElement___toString, ZEND_ACC_PUBLIC) + SXE_ME(toString, arginfo_class_SimpleXMLElement_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) SXE_ME(count, arginfo_class_SimpleXMLElement_count, ZEND_ACC_PUBLIC) PHP_FE_END }; @@ -2633,7 +2648,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/simplexml/simplexml.stub.php b/ext/simplexml/simplexml.stub.php index 3a1d0d51f4e3e..ca0aa837c208a 100644 --- a/ext/simplexml/simplexml.stub.php +++ b/ext/simplexml/simplexml.stub.php @@ -6,7 +6,7 @@ function simplexml_load_string(string $data, ?string $class_name = SimpleXMLElem function simplexml_import_dom(DOMNode $node, ?string $class_name = SimpleXMLElement::class): ?SimpleXMLElement {} -class SimpleXMLElement +class SimpleXMLElement implements Stringable { /** @return array|false */ public function xpath(string $path) {} @@ -46,6 +46,8 @@ public function getName() {} /** @return string */ public function __toString() {} + final public function toString(): string {} + /** @return int */ public function count() {} } diff --git a/ext/simplexml/simplexml_arginfo.h b/ext/simplexml/simplexml_arginfo.h index b44426beebf57..998a38d68011f 100644 --- a/ext/simplexml/simplexml_arginfo.h +++ b/ext/simplexml/simplexml_arginfo.h @@ -73,4 +73,7 @@ ZEND_END_ARG_INFO() #define arginfo_class_SimpleXMLElement___toString arginfo_class_SimpleXMLElement_getName +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_SimpleXMLElement_toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + #define arginfo_class_SimpleXMLElement_count arginfo_class_SimpleXMLElement_getName diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c index da61c41f0e236..7ea9c6d489fa2 100644 --- a/ext/spl/spl_directory.c +++ b/ext/spl/spl_directory.c @@ -1415,6 +1415,20 @@ SPL_METHOD(SplFileInfo, _bad_state_ex) } /* }}} */ +/* {{{ proto string SplFileInfo::toString() + Return the string representation of the object */ +SPL_METHOD(SplFileInfo, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} +/* }}} */ + /* {{{ proto FilesystemIterator::__construct(string path [, int flags]) Cronstructs a new dir iterator from a path. */ SPL_METHOD(FilesystemIterator, __construct) @@ -1854,7 +1868,7 @@ static int spl_filesystem_object_cast(zend_object *readobj, zval *writeobj, int spl_filesystem_object *intern = spl_filesystem_from_obj(readobj); if (type == IS_STRING) { - if (readobj->ce->__tostring) { + if (zend_class_implements_interface(readobj->ce, zend_ce_stringable) || readobj->ce->__tostring) { return zend_std_cast_object_tostring(readobj, writeobj, type); } @@ -1899,6 +1913,9 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_splfileinfo_void, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_splfileinfo_toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + /* the method table */ /* each method can have its own parameters and visibility */ static const zend_function_entry spl_SplFileInfo_functions[] = { @@ -1934,6 +1951,7 @@ static const zend_function_entry spl_SplFileInfo_functions[] = { SPL_ME(SplFileInfo, setInfoClass, arginfo_info_optinalFileClass, ZEND_ACC_PUBLIC) SPL_ME(SplFileInfo, _bad_state_ex, NULL, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) SPL_MA(SplFileInfo, __toString, SplFileInfo, getPathname, arginfo_splfileinfo_void, ZEND_ACC_PUBLIC) + SPL_ME(SplFileInfo, toString, arginfo_splfileinfo_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) PHP_FE_END }; @@ -3104,6 +3122,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_iterators.c b/ext/spl/spl_iterators.c index 5e021ce493ea6..90aa5a030b7fe 100644 --- a/ext/spl/spl_iterators.c +++ b/ext/spl/spl_iterators.c @@ -61,6 +61,9 @@ PHPAPI zend_class_entry *spl_ce_RecursiveTreeIterator; ZEND_BEGIN_ARG_INFO(arginfo_recursive_it_void, 0) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_caching_it_toString, 0, 0, IS_STRING, 0) +ZEND_END_ARG_INFO() + static const zend_function_entry spl_funcs_RecursiveIterator[] = { SPL_ABSTRACT_ME(RecursiveIterator, hasChildren, arginfo_recursive_it_void) SPL_ABSTRACT_ME(RecursiveIterator, getChildren, arginfo_recursive_it_void) @@ -2736,8 +2739,19 @@ SPL_METHOD(CachingIterator, __toString) } } /* }}} */ -/* {{{ proto void CachingIterator::offsetSet(mixed index, mixed newval) - Set given index in cache */ +/* {{{ proto string CachingIterator::toString() + Return the string representation of the current element */ +SPL_METHOD(CachingIterator, toString) +{ + zval rv; + + ZEND_PARSE_PARAMETERS_NONE(); + + zend_call_method_with_0_params(Z_OBJ_P(ZEND_THIS), NULL, NULL, "__tostring", &rv); + + ZVAL_COPY_VALUE(return_value, &rv); +} /* }}} */ + SPL_METHOD(CachingIterator, offsetSet) { spl_dual_it_object *intern; @@ -2950,6 +2964,7 @@ static const zend_function_entry spl_funcs_CachingIterator[] = { SPL_ME(CachingIterator, next, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, hasNext, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, __toString, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) + SPL_ME(CachingIterator, toString, arginfo_caching_it_toString, ZEND_ACC_PUBLIC|ZEND_ACC_FINAL) SPL_ME(dual_it, getInnerIterator, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, getFlags, arginfo_recursive_it_void, ZEND_ACC_PUBLIC) SPL_ME(CachingIterator, setFlags, arginfo_caching_it_setFlags, ZEND_ACC_PUBLIC) @@ -3669,6 +3684,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..9c04b0056ef3b 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..9a2883714a47b 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..abc0f6b552256 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..d25b89b61f28e 100644 Binary files a/ext/standard/tests/strings/ucfirst.phpt and b/ext/standard/tests/strings/ucfirst.phpt differ diff --git a/sapi/cli/tests/005.phpt b/sapi/cli/tests/005.phpt index d268104606350..62b1115a13b3b 100644 --- a/sapi/cli/tests/005.phpt +++ b/sapi/cli/tests/005.phpt @@ -37,7 +37,7 @@ string(183) "Class [ class stdClass ] { } " -string(1969) "Class [ class Exception implements Throwable ] { +string(2132) "Class [ class Exception implements Throwable, Stringable ] { - Constants [0] { } @@ -58,7 +58,7 @@ string(1969) "Class [ class Exception implements Throwable ] { Property [ private $previous ] } - - Methods [11] { + - Methods [12] { Method [ final private method __clone ] { - Parameters [0] { @@ -127,6 +127,13 @@ string(1969) "Class [ class Exception implements Throwable ] { - Parameters [0] { } } + + Method [ final public method toString ] { + + - Parameters [0] { + } + - Return [ string ] + } } }