Re: PHP 7.1 - Address PHPSadness #28?
| From: | Robert Williams | Date: | Tue, 15 Sep 2015 09:38:08 +0000 |
| Subject: | Re: PHP 7.1 - Address PHPSadness #28? | ||
| References: | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-88209@lists.php.net to get a copy of this message | ||
On Sep 14, 2015, at 16:06, Stanislav Malyshev <smalyshev@gmail.com> wrote:
>
>>> No. There's no reason for null to exist if isset returns true on
>>> null. If one doesn't understand that, one should not be using
>>> null at all.
>>
>> Nonsense.
>
> Oh, thank you! That's a good start for a polite argument.
Apologies, no offense intended, but you do realize that you essentially said that any programmer who
doesn't agree with what you profess is the One True Way, is doing it wrong? This type of
statement has been made several times in this thread, and it's annoyingly dismissive. Given how
PHP has evolved, and how many architectural inconsistencies there are, I'm not so sure there is
a One True Way.
>> It just means that one isn’t using null the way you do.
>
> No, it means one isn't using null the way it is intended to be used in
> the language.
It really seems to me that PHP is fundamentally confused in how it wants to treat null. It clearly
has the concept of an undefined variable: variable existence is referenced throughout the docs along
with null-ness (e.g., the docs for isset() say it returns true if the variable, "is set and is
not null" and if the variable, "exists and has value other than null"), it throws
undefined errors for using variables that aren't defined, and it even has an unset() construct
that leads to an undefined variable that fails isset(). Yet, it also defines undefined variables as
being null -- which is it? Even is_null() is caught up in this: it will throw an undefined error if
passed an undefined variable while also returning true. Why an error for a value that supposedly
fits the definition of null?
>> functions do. As I said, they’re misguided, right up there with
>> register_globals. (They lead to similar security bugs, too.)
>
> Please do not bring "security" as some superman-argument, expecting
> that is you say "security" your arguments suddenly become so much
> stronger. There's no special security problem here besides the trivial
> fact that if you write buggy code in security-sensitive context, you
> get security issue. So please leave security out of it.
Re-read what I said. I didn't say any of this was a security bug. I said it can lead to
security bugs. And that is, I think, undeniably true because null handling in PHP is clearly
confusing to a lot of folks, and any confusing API (buggy or not) will tend to lead to
application-level security bugs if that API is often used in security contexts. Hasn't a bunch
of work recently been completed with hashing and encryption APIs for this very reason? Same idea.
I also mentioned the security issue parenthetically, as a side-note, so please don't accuse me
of overplaying the security card. My main point there was that isset() and empty() were
ill-conceived.
And again, who's doing the bashing here? Ease off a bit -- I'm really not trying to attack
you at all.
>> If a variable that’s declared yet defined as null can’t “exist” as
>> decided by isset(), why can an array element that’s declared yet
>> defined as null “exist” as decided by array_key_exists()? Is the
>
> Because these are two different functions doing different things.
> That's like asking why strlen returns string length but fopen does not
> return file length.
Clearly, they're different functions, but I think they're doing something different only
so far as they operate in different contexts. Their purposes are closely related, IMHO, which is why
they keep being paired together in this thread and why people keep using one when they should be
using the other. If we allow that, then it would make sense for them to function similarly.
Okay, so to bring this home:
1 PHP defines null to include variables that have "not been set"
2 PHP also defines null to include variables that have been unset()
3 Variables can be explicitly set to null
All of these are null. And yet:
4 Calling isset(), which is documented to return true on null, on 1, 2, and 3 will only return true
for 3.
How's this consistent?
Returning true on 1 and 2 suggests clearly that PHP does distinguish between undefined variables and
null variables. This supposition is also supported by numerous mentions of these concepts in the
docs and by the various undefined error messages that PHP produces. It goes off the tracks, however,
when it returns true for 3.
IMHO, PHP went south in its design when it tried to declare undefined variables as null.
They're not; they're undefined. Beyond isset/empty/is_null, however, the rest of PHP seems
to accept this. Even the three deviant functions tacitly acknowledge the issue in their
documentation, e.g. with isset()'s existence requirement as part of a compound statement
("exists and has value other than null"). PHP falls short, however, in not providing a way
to independently test each part of that compound statement.
Ideally, we would reverse course on the undefined-is-null declaration then adjust
isset/empty/is_null accordingly, but I realize that opens a large can of worms. Providing a simple
exists() function doesn't solve the root issue, but it at least gives a way to directly test
for a very real condition: the first half of the isset() compound requirements statement. If we can
do that, we will have what we need to mostly regard the null design error as an academic matter with
relatively little real-world consequence going forward.
Regards,
Bob