Hi Lynn, thank you for sharing your thoughts.

Le ven. 23 janv. 2026 à 12:44, Lynn <[email protected]> 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

Reply via email to