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
