On Sat, Jul 12, 2025, at 01:29, Theodore Brown wrote: > On Fri, July 11, 2025 at 05:00 G. P. Banyard wrote: > > >> On Monday, 30 June 2025 at 10:26, Nicolas Grekas wrote: > >> ... > >> The latter, cast-from-bool, I think they're all useful improvements. While > >> most likely harmless in all the specific > >> cases of the PR, doing e.g. an strpos() on false feels hardly legit. I'm > >> therefore sympathetic to making these changes. > >> > >> For cast-to-bool, I'm WAY less convinced. From the PR above, explicit > >> casts like "return (bool) preg_match(...)" > >> on a method that returns a "bool" or "(bool) ($this->loggedErrors & > >> $type)" are a clear downgrade: it makes the > >> typing PHP just more verbose without any real benefit. That doesn't look > >> worth asking the whole ecosystem to fix > >> those deprecations. It is especially hard to see this as an improvement > >> when comparing to using the same > >> expressions with e.g. the "if ()" operator, which doesn't need the > >> explicit cast (and shouldn't of course). > > From my experience there is a very real benefit to deprecating both > cast-from-bool and cast-to-bool. > Let me give an example of both. > > Recently had to fix some legacy code where the result of `filemtime` was > being passed to `gmdate` to format > the modification timestamp. `filemtime` returns false on failure, but this is > silently coerced to zero > (a valid timestamp) when passed to the int parameter, which would result in > the script continuing with bad > data instead of halting with a type error. > > Cast-to-bool can cause the same kinds of issues, which are sometimes even > harder to notice. Consider the following: > > function processArray(array $items, bool $hasCertainKey) { ... } > > $keyOrFalse = array_search('my value', $items); > > processArray($items, $keyOrFalse); > > It's very easy to miss the bug in this code, especially since it seems to > function correctly as long as 'my value' > is not in the array, or is not the first item in the array. However, when > it's at index 0 the key will be silently > coerced to false and the array will be incorrectly processed as though the > value is not in the array. > > I believe deprecating type juggling to/from bool will help avoid creating > bugs like this (and likely > surface existing ones that should be fixed). > > Kind regards, > Theodore
I'm not so confident that will be the case. In lots of strict-mode code I've worked with over the years, people tend to blindly cast things without realizing they're in a worse situation than using non-strict mode. Like `((int)"123password") === 123`, however attempting to coerce that string to an int results in a proper type error in non-strict mode. That is to say, I highly suspect that `gmdate(filemtime($file))` would just be rewritten as `gmdate((int)filemtime($file))` without a second thought. In your other example showing the difference in array_search, I also highly suspect people would just cast it to bool without noticing the 0-key edge case. Both cases, I believe, can simply be solved by tooling highlighting when you're passing a union type to a function that doesn't overlap with the function's expectations. ("you are passing int|string to a function expecting bool" and/or "you are casting int|string to bool, check that (bool)"0" won't be an edge-case; consider using empty() instead"). — Rob