Hi Lynn, thank you for sharing your thoughts.
Le ven. 23 janv. 2026 à 12:44, Lynn <kjarli@gmail.com> a écrit :
> What's the expected behavior of `(int) '001'` and `(int) 1.`? I would expect both to still be valid integers, but I can't tell from this RFC if those scenarios would be affected. The first scenario is common with "ZEROFILL" database columns, and the latter is a scenario I recently found being used to get a valid int from user input if considered number-ish and switch between whole number vs decimal behavior.
They will be indeed valid integers. There is no lossy cast here: "001"
and "1." are valid integers and expected.
> I'm afraid that deprecating and eventually erroring these casts will break a lot of hard to trace legacy code, where a cast "solved" most problems, or at least did not crash things. I'm talking about values that come from automated import systems, go through dozens of layers of code that haven't been touched since php 5.2 or earlier, and eventually end up in a part where we do a cast. It was also not unthinkable that these casts were used _because_ it truncated the invalid parts, and while we could replace this with a preg_match to extract the number, I don't particularly feel like going through nearly 5k int casts in this codebase and figure out if it should change or not.
I understand the concern about legacy code. However, if code relies on
`(int) "123abc"` silently returning `123`, this represents a data
integrity issue that would benefit from being made explicit. The
deprecation period exists specifically to help identify and address
these cases.
> Does this behavior als affect parameters being passed in a non-strict fashion? Because then I don't see a realistic migration path within the next decade for this application.
This behavior already exists and forbids such casts, see
https://3v4l.org/WQJPv#vnull.
> On the subject of strings, I'm very afraid this will cause hidden issues. The Stringable value isn't always the value I want from an object, and with this change my IDE will no longer give an error that it's the wrong type.
This is exactly the intended behavior: Stringable *is* an explicit
contract informing that an object can be converted to string.
Non-strict mode is aligned with that, whereas strict mode misleadingly
forbids that. Default mode has better casting rules that strict mode
doesn't offer. The whole "non-strict community" uses this rule, making
their code simpler by not having to deal with a union type every time.
> I foresee people throwing stringable objects into string parameters and silently causing the wrong values to be used.
Again, Stringable is an explicit contract to define the appropriate
string representation of an object. If this is a problem, the issue
lies in the `__toString()` implementation.
> This will also silently break values being passed if the __toString implementation changes, which is going to be extremely hard to trace back like with `(string) $object`.
If any `__toString()` implementation changes in your object, it will
already break everywhere the object is casted to string or used in a
string context. This is an API breaking issue, which, to me, feels
unrelated to the RFC.
> This change also makes reviewing code more difficult as I have to know the parameter type, variable type, and what the __toString function does in order to find out if it's correct, or another value had to be passed.
With `string|Stringable`, you have to check two types (even if
`Stringable` is meant to be an explicit contract). With just `string`
that accepts Stringable, it's simpler and more consistent. The code
will also be less error-prone.
— Alexandre Daubois