php · GitHub

Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,8 @@ PHP 8.0 UPGRADE NOTES
. Some consistency fixes to variable syntax have been applied, for example
writing `Foo::BAR::$baz` is now allowed.
RFC: https://wiki.php.net/rfc/variable_syntax_tweaks
. Added Stringable.
RFC: https://wiki.php.net/rfc/stringable

- Date:
. Added DateTime::createFromInterface() and
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ try {
--EXPECT--
Hello World!
===NONE===
Method NoneTest::__toString() must return a string value
Return value of NoneTest::__toString() must be of type string, none returned
Comment thread

nicolas-grekas marked this conversation as resolved.

Outdated

===THROW===
This is an error!
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
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
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
--TEST--
Stringable is automatically implemented
--FILE--
<?php

class Test {
public function __toString() {
return "foo";
}
}

var_dump(new Test instanceof Stringable);
var_dump((new ReflectionClass(Test::class))->getInterfaceNames());

class Test2 extends Test {
public function __toString() {
return "bar";
}
}

var_dump(new Test2 instanceof Stringable);
var_dump((new ReflectionClass(Test2::class))->getInterfaceNames());

?>
--EXPECT--
bool(true)
array(1) {
[0]=>
string(10) "Stringable"
}
bool(true)
array(1) {
[0]=>
string(10) "Stringable"
}
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 implements Stringable {
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 {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

Expand Down Expand Up @@ -160,7 +160,7 @@ float(0)
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

Expand Down Expand Up @@ -213,7 +213,7 @@ string(0) ""
}
*** Caught {closure}(): Argument #1 ($s) must be of 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 {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

Expand Down
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 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 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 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 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 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 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 type bool, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down
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 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 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 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 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 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 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 type bool, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down
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 {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

Expand Down Expand Up @@ -153,7 +153,7 @@ float(NAN)
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

Expand Down Expand Up @@ -206,7 +206,7 @@ string(0) ""
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

Expand Down Expand Up @@ -259,7 +259,7 @@ bool(false)
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

Expand Down
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 {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

Expand Down Expand Up @@ -153,7 +153,7 @@ float(NAN)
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

Expand Down Expand Up @@ -206,7 +206,7 @@ string(0) ""
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

Expand Down Expand Up @@ -259,7 +259,7 @@ bool(false)
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
--TEST--
Automatic Stringable implementation participates in variance
--FILE--
<?php

class Foo {
public function test(): Stringable {}
}
class Bar extends Foo {
public function test(): Bar {}
public function __toString() {}
}

?>
===DONE===
--EXPECT--
===DONE===

Read the original on github.com ↗