On 3 May 2022, at 14:55, Rowan Tommins <rowan.coll...@gmail.com> wrote:
> 
> On 03/05/2022 12:37, Craig Francis wrote:
>> But what is that benefit? I'm sorry, but I really don't see it.
> 
> 
> I started drafting a longer reply, but honestly I don't think we're getting 
> anywhere. Every attempt to explain the benefit seems to end in one of two 
> ways:
> 
> - an endless back and forth nit-picking hypothetical situations where it 
> might or might not be useful
> - an outright dismissal that "people who want it strict can go over there and 
> use strict_types=1 and/or static analysis"
> 
> To me, it's *always* about trade-offs: the *benefit* of strict checks exists 
> for everyone, and the question is whether they want to pay the *cost* or not. 
> As long as we can't agree on that fundamental point, there's no point 
> continuing the discussion.


I hope I don't come across like that; I'm really trying to understand the 
benefits and costs (I tend to use small examples to help myself understand).

I'm not trying to be dismissive with the use of static analysis. I just think 
PHP should be tolerant of some things (e.g. string '5' to int 5, and null to 
empty string), but I also recognise some developers prefer a very strict 
environment that does not do any type coercion (that's where I think static 
analysis works really well, as it can enforce extra checks, including type 
checks for all variables from all sources to all sinks).

That said, I do see value in some Type Errors, like how I updated my RFC a 
couple of weeks ago with some examples "like `substr($string, “offset”)` and 
`htmlspecialchars(array())` as being clearly problematic" (thanks again George).

I'm also fine with `substr('abc', $offset)` rejecting an Empty String or NULL 
for `$offset` (I'll note that `$offset` was never added to my list of 335 
parameters).

Under "Future Scope" I've given 4 example parameters that probably should 
reject an Empty String or NULL (because they do represent problems, similar to 
how `$separator` in `explode()` already has the “cannot be empty” fatal error).

And finally, I can see how `mt_rand(NULL, NULL)` could be a problem (someone 
assuming NULL represents a default value, but it's coerced to the integer 0), 
but as I noted in my previous email, I cannot find anyone doing this, and after 
re-checking my lists and having a re-look though the manual, I think it's the 
only one that benefits from the rejection of NULL coercion.

Taking that as my rough position on type coercion, I don't see a *benefit* from 
blocking NULL coercion (more below).

Whereas, blocking NULL coercion does introduce an upgrade *cost* (not made 
easier due to the lack of tooling); and the continuing cost to some developers 
using the noted frameworks or `filter_input()` (e.g. always specifying an empty 
string default, or always manually casting NULL to a string)... the other cost 
is the weirdness in how NULL coercion still works for echo()/print(), string 
concatenation, == comparisons, arithmetics, sprintf, etc.



>> I'm going on the basis that you're ok with numbers in strings being coerced 
>> to integers/floats (which I also see as being useful, because you're right, 
>> most inputs are strings)... but you're not ok with NULL being coerced (which 
>> is also common, because values aren't guaranteed to be provided by the user, 
>> and NULL is typically the default).
> 
> 
> I will reply to this point, though, because I think it's a genuinely 
> interesting thing to ponder.
> 
> One significant difference is that not only is it often not *useful* to 
> distinguish an input of 123 from '123', it's often not *possible*. There is 
> literally no way for an HTTP URL or header to contain an integer, rather than 
> a string representation of one, because it's not a binary protocol.
> 
> On the other hand, you might well receive an empty string as input where 
> you're expecting an integer. Notably, that is *not* coerced automatically to 
> zero; the code has to explicitly decide if that should trigger distinct 
> behaviour (such as a validation error) or be treated as a default value. Not 
> receiving a field you expected feels very similar, so similar behaviour feels 
> reasonable.


I'm someone who will try to justify some very strict coding styles - like no 
inline JavaScript, use of Trusted Types, the use of literal-string for 
SQL/HTML/etc, and in some cases the use of application/xhtml+xml (these have 
easily provable benefits, but they can also be tricky, so few developers use 
them).

With your example, I'm probably fine with an Empty String or NULL not being 
coerced to int 0 (as in, I could see how it might represent a problem, although 
I wouldn't care if it did get coerced to 0).

But a lot of existing PHP code simply takes user input (which can be NULL), and 
passes it to these functions with no expectation of a fatal error (not good if 
it's in mid-way though processing data).

If we were talking about a desktop application, where the UI was defined and 
displayed by that application, then a missing field would represent a problem 
in that application, but we're typically talking about the web with PHP, where 
the data often comes from an un-trusted browser... i.e. the 
user/browser/extension/network can be doing something odd, all the way down to 
how a standard HTML checkbox works (unchecked does not provide a field).

It's because of these oddities, and the way NULL has historically worked, many 
developers simply don't see the difference between an empty or missing field 
(like other sources of NULL).

That's why I don't see any benefit to blocking NULL coercion in this context, 
as an Empty String or NULL are often seen as the same - e.g. a programmer is 
simply checking if a name was provided, checking an email address contains the 
'@' character, checking if a message is too long, trimming the whitespace from 
a value, getting a record with an id/slug/name/ref, adding the value to a url, 
showing the search term, etc.

Craig

--
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: https://www.php.net/unsub.php

Reply via email to