Take the State of PHP 2026 Survey →

Stringable View as Markdown

Implemented (PHP 8.0)
Authors
Nicolas Grekas, nicolasgrekas@php.net
Date
2020-01-15
Version
0.9
Source
wiki.php.net/rfc/stringable

Vote

Adopt the Stringable interface as proposed in this RFC? closed
Yes
29
No
9
38 voters
alcaeus Yes 2020-02-14 11:16
alec Yes 2020-02-14 07:03
asgrim Yes 2020-02-13 15:17
ashnazg Yes 2020-02-12 22:27
beberlei Yes 2020-02-12 14:48
bwoebi Yes 2020-02-12 14:38
carusogabriel Yes 2020-02-15 18:40
colinodell Yes 2020-02-12 14:44
derick Yes 2020-02-13 01:29
dm Yes 2020-02-24 20:59
dmitry No 2020-02-17 08:21
duncan3dc Yes 2020-02-14 14:27
galvao Yes 2020-02-13 04:55
geekcom Yes 2020-02-13 14:48
girgias Yes 2020-02-12 15:30
heiglandreas Yes 2020-02-12 15:02
jhdxr No 2020-02-23 15:29
jpauli Yes 2020-02-13 13:22
kalle No 2020-02-12 16:25
kocsismate No 2020-02-13 15:13
mariano Yes 2020-02-12 17:09
mbeccati Yes 2020-02-12 15:49
nicolasgrekas Yes 2020-02-12 14:39
ocramius Yes 2020-02-13 09:44
patrickallaert No 2020-02-12 17:52
peehaa No 2020-02-12 16:18
ramsey No 2020-02-12 23:02
rasmus No 2020-02-13 21:35
reywob Yes 2020-02-12 15:26
ruudboon Yes 2020-02-12 15:41
sorin Yes 2020-02-13 11:29
stas No 2020-02-12 20:05
svpernova09 Yes 2020-02-12 14:56
tandre Yes 2020-02-15 22:39
weierophinney Yes 2020-02-24 18:47
wyrihaximus Yes 2020-02-15 14:27
yunosh Yes 2020-02-13 09:14
zimt Yes 2020-02-22 11:23

Discussions on the mailing list

[RFC] Adding a "Stringable" interface to PHP 8
by Nicolas Grekas · 16 messages
[VOTE] Stringable
by Nicolas Grekas · 4 messages

RFC text

Copied from wiki.php.net, last synchronized Oct 13, 2026 11:51 UTC

Introduction

This RFC introduces a new Stringable interface that is automatically added to classes that implement the __toString() method.

It has two goals:

  1. allow using string|Stringable to express string|object-with-__toString()
  2. provide a forward upgrade path from PHP 7 to 8

Proposal

Goal 1. is to allow using the string|Stringable union type in PHP 8, to accept both strings and objects that implement __toString(). This is critically missing currently, on codes that deal with stringable objects: they can't be made type-safe.

Classes that implement __toString() can also declare the interface explicitly. Classes that don't declare the interface explicitly will still declare it implicitly. This allows both forward compatibility and backward compatibility: using a polyfill, classes can declare the interface on PHP 7; and on PHP 8, classes that don't do so will still be compatible with the string|Stringable union type.

Once a polyfill becomes widely available (e.g. as part of symfony/polyfill-php80), code style checkers could be able to enforce declaring the interface when __toString() is declared explicitly, for people that prefer doing so.

Here is the stub declaration of the interface:

interface Stringable
{
   public function __toString(): string;
}

Because it adds the string return type, this interface has the potential to force a BC break on any existing libraries that want to adopt it.

In order to ease forward and backward compatibility, this RFC also proposes to automatically add the return type at compile time when a __toString() method doesn't do it explicitly already. Returning a string is already enforced by the engine so this doesn't change any semantics.

This way, code moving to PHP8 won't be forced to add the return type explicitly (which would break BC on their side), and code in PHP < 8 can adopt a polyfill interface immediately (one that doesn't declare the return type for the same BC reasons.)

Providing an easy forward-path is the second goal of this RFC.

For reference, here are some annotations in Symfony, added by contributions from real-world use cases and that currently cannot be expressed precisely enough using any union types in PHP 8.

Backward Incompatible Changes

Codes that declare a symbol named Stringable in the root namespace will have to rename it.

Proposed PHP Version(s)

PHP 8.0

RFC Impact

To Existing Extensions

Extensions will need to declare both the interface and the string return type when they declare __toString() methods if they want to pass the string|Stringable union type.

Open Issues

none

Unaffected PHP Functionality

Declaring this interface is not mandatory to benefit from the magic of the __toString() method.

Future Scope

void

Proposed Voting Choices

yes/no

Vote

Vote: Adopt the Stringable interface as proposed in this RFC? — Yes: 29 · No: 9 (closed)

Patches and Tests

https://github.com/php/php-src/pull/5083/files

Implementation

After the project is implemented, this section should contain

  1. the version(s) it was merged into
  2. a link to the git commit(s)
  3. a link to the PHP manual entry for the feature
  4. a link to the language specification section (if any)

References

https://github.com/php/php-src/pull/5083

Rejected Features

  1. Adding a new stringable special type (like iterable, callable, etc.) is not considered in this RFC because it would require adding a new reserved keyword in the language. This would break BC more heavily and would defeat goal #2 mentioned previously (ability to polyfill on PHP7.)
  2. Consistently, this RFC doesn't embed any is_stringable() function. If we were to consider one, defining what happens when e.g. an int is passed has no simple answers.
  3. it has been proposed on the GitHub PR that the method attached to the interface could be named toString() instead of __toString(). This idea goes further than strictly required to achieve goal #1 and has been objected as not necessary in the following comments. For reference, here is a naive implementation of the proposal. What the patch highlights is that this increases the complexity of the engine, for a reason that would need to be justified.