rfc:allow-stringable-string-param-strict-mode

PHP RFC: Allow Stringable For String Parameters in Strict Mode

Summary

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.

Introduction

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.

Motivation

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:

  • Inconsistent behavior: The same code behaves differently between strict and non-strict modes for a well-defined conversion
  • Verbose workarounds: Developers must use patterns like 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:

  • Respects the explicit Stringable contract
  • Reduces special cases in conversion behavior
  • Aligns with the longer-term direction of reducing the gap between typing modes (see the Unify PHP's typing modes gist)
  • Does not compromise type safety, as the conversion is well-defined and guaranteed by the interface

Proposal

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!"
?>

Backward Compatibility Impact

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.

Proposed PHP Version

Next minor (PHP 8.6)

RFC Impact

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.

Vote

Single yes/no vote requiring 2/3 majority.

Allow Stringable in strict mode in PHP 8.6?
Real name Yes No Abstain
Final result: 0 0 0
This poll has been closed.

Voting opens [TBD] and closes [TBD].

References

rfc/allow-stringable-string-param-strict-mode.txt · Last modified: by alexandredaubois