Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Define Stringable with toString():string method
  • Loading branch information
nicolas-grekas committed Jan 15, 2020
commit c96e6c965a68bdd798598580e1d05b27cdfbaa38
2 changes: 1 addition & 1 deletion Zend/tests/list_keyed_evaluation_order.inc
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
4 changes: 2 additions & 2 deletions Zend/tests/list_keyed_evaluation_order.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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"]));

Expand Down
10 changes: 5 additions & 5 deletions Zend/tests/list_keyed_evaluation_order_nested.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $functions = [
'bool' => function (bool $b) { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -40,7 +40,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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"

Expand Down Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_return_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $functions = [
'bool' => function ($b): bool { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -42,7 +42,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_return_basic_64bit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $functions = [
'bool' => function ($b): bool { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -42,7 +42,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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)
Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_strict.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ $functions = [
'bool' => function (bool $b) { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -34,7 +34,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_strict_64bit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ $functions = [
'bool' => function (bool $b) { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -34,7 +34,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down Expand Up @@ -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

Expand Down
19 changes: 17 additions & 2 deletions Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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
};

Expand All @@ -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);
Expand All @@ -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);
Expand Down
4 changes: 3 additions & 1 deletion Zend/zend_exceptions.stub.php
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<?php

interface Throwable
interface Throwable extends Stringable
{
/** @return string */
function getMessage();
Expand Down Expand Up @@ -56,6 +56,8 @@ final function getPrevious() {}
/** @return string */
final function getTraceAsString() {}

final function toString(): string {}

/** @return string */
function __toString() {}
}
Expand Down
3 changes: 3 additions & 0 deletions Zend/zend_exceptions_arginfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ ZEND_END_ARG_INFO()

#define arginfo_class_Exception___toString arginfo_class_Throwable_getMessage

ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_class_Exception_toString, 0, 0, IS_STRING, 0)
ZEND_END_ARG_INFO()

ZEND_BEGIN_ARG_INFO_EX(arginfo_class_ErrorException___construct, 0, 0, 0)
ZEND_ARG_TYPE_INFO(0, message, IS_STRING, 0)
ZEND_ARG_TYPE_INFO(0, code, IS_LONG, 0)
Expand Down
Loading