Hi Rowan,

Le ven. 23 janv. 2026 à 15:55, Rowan Tommins [IMSoP]
<[email protected]> a écrit :
> I am strongly against the Stringable part of this.
>
> It would mean users who have explicitly asked for no type coercion would get 
> silent type coercion. It would mean that a string parameter in mode 1 would 
> still reject an integer 42, but would *accept* new BcMath\Number(42). I can't 
> see how that makes sense.

Stringable is an explicit contract that an object can be safely
converted to a string. If an application breaks because of such a
cast, this means the implementation of the `__toString()` method is
buggy and does not respect the contract. Currently, non-strict and
strict modes differ on Stringable handling, and I'm not aware of this
non-strict behavior causing bugs in production applications - though
I'd genuinely welcome counterexamples if you're aware of any.

Regarding your BcMath\Number example: I see the distinction you're
making, but I think the key difference is the *explicit opt-in*. An
integer doesn't choose to be convertible to string - that's a built-in
coercion. A class implementing Stringable explicitly declares "I have
a canonical string representation". The parallel would be: strict mode
rejects int -> string coercion (implicit), but should accept
Stringable -> string because it's an explicit contract, much like it
accepts objects implementing ArrayAccess for array operations in
certain contexts.

As mentioned by Larry, Stringable changes would deserve another RFC.
We're considering creating a second RFC just for the Stringable part,
so I propose to continue this discussion in the coming thread if that
suits you, so we can keep things organised.

> As I've said elsewhere, I think the right approach to this is to design a new 
> set of cast operations, with a more extendable syntax. They can have more 
> clearly defined rules for "int-like string" etc, and different modes/variants 
> for use cases like "error on failure" vs "default value on failure".

Our goal is to make things more consistent and simple, and I'm afraid
creating a new set of casts would just overcomplexify things. The
fundamental problem would be shifted to somewhere else, not solved.
Adding new cast operators would create a third set of rules alongside
type coercion and type declarations. Aligning existing casts with the
type checking semantics that have been standard since PHP 7.0 seems
simpler and more maintainable long-term.

— Alexandre Daubois

Reply via email to