This RFC proposes to accept Stringable objects for string type declarations in strict typing mode.
Currently, strict mode (declare(strict_types=1)) rejects Stringable values for string parameters, even though they have a well-defined string representation through the __toString() method.
In strict typing mode, passing a Stringable object to a string parameter throws TypeError. In the default typing mode, the same call is accepted and the object is converted via __toString().
<?php declare(strict_types=1); function process(string $value): void { } $obj = new class implements Stringable { public function __toString(): string { return "hello"; } }; process($obj); // TypeError (works in non-strict mode) ?>
This inconsistency between typing modes requires workarounds despite Stringable being an explicit contract for safe string conversion.
The Stringable interface was introduced in PHP 8.0 as an explicit contract indicating that an object can be safely converted to a string. However, strict typing mode still rejects these objects for string parameters.
This results in several issues:
string|Stringable unions with manual casting, or require callers to cast with (string) $value
Accepting Stringable in strict mode for string parameters is a natural relaxation that:
Stringable contract
Strict mode will accept Stringable objects for string parameters, converting them via __toString():
<?php declare(strict_types=1); function greet(string $name): string { return "Hello, $name!"; } $user = new class implements Stringable { public function __toString(): string { return "John"; } }; greet($user); // PHP 8.5: TypeError, PHP 8.6: "Hello, John!" ?>
This is a relaxation of type checking, not a breaking change. Code that currently works will continue to work.
The only potential compatibility issue is code that explicitly relies on strict mode rejecting Stringable objects. Most code receiving a string parameter treats it as a string value and does not care whether it originated from a Stringable object.
Next minor (PHP 8.6)
Projects using strict types are expected to benefit from reduced verbosity and more consistent behavior. This rule aligns with the existing non-strict mode behavior, where Stringable is already accepted for string parameters.
Single yes/no vote requiring 2/3 majority.
Voting opens [TBD] and closes [TBD].