Re: PHP 7.1 - Address PHPSadness #28?
| From: | Craig Francis | Date: | Tue, 01 Sep 2015 09:29:10 +0000 |
| Subject: | Re: PHP 7.1 - Address PHPSadness #28? | ||
| References: | 1 2 3 4 5 6 7 8 | Groups: | php.internals |
| Request: | Send a blank email to internals+get-87987@lists.php.net to get a copy of this message | ||
Hi Rowan, Ryan, James, Bishop, Stas, Lester,
I've been giving this some thought over the weekend, and I agree with what you are all saying,
but I think there is an element of confusion in the PHP programming community that needs to be
addressed (somehow).
Yes, we probably should not be giving special meaning to NULL, as James mentions (although I
probably still will).
And to be fair, I still can't think of an example where isset() can be used on a standard
variable. All my examples are really array based, and better addressed with array_key_exists() -
where Rowan does a great job of explaining the different examples on stackoverflow:
http://stackoverflow.com/a/18646568/2908724
Trying to get to route of the confusion though, I think it might be down to how the code can be
read. So if we take:
<?php
$a = 1;
$b = NULL;
var_dump($a);
var_dump($b);
var_dump($c);
var_dump(isset($a));
var_dump(isset($b));
var_dump(isset($c));
?>
Or using an array instead:
<?php
$v['a'] = 1;
$v['b'] = NULL;
var_dump($v['a']);
var_dump($v['b']);
var_dump($v['c']);
var_dump(isset($v['a']));
var_dump(isset($v['b']));
var_dump(isset($v['c']));
?>
In both cases (and ignoring the undefined variable error), we get:
int(1)
NULL
NULL
bool(true)
bool(false)
bool(false)
But if we ignore the manual for a minute:
http://php.net/isset
I think a good comparison to what that code reads as, vs what PHP does, can be summarised as:
Read as: The variable is set (exists).
Executed as: The variables *value* is set.
Where NULL is not considered a set value.
So when we have:
if (isset($v['a'])) {
}
It's not saying that the key 'a' is set (exists) on the array $v.
Instead its saying that the key 'a' has a set value (not NULL) on the array $v.
Where this is made more of a common problem because there are many array_* functions, and they
rarely come to mind when your not thinking of an array like operation.
This situation might be improved by re-wording the manual a bit.
Having headings like "This also work[s] for elements in arrays", makes it sound all
inclusive and *the* function to use.
Whereas I'm starting to get the feeling that isset() is actually a function that probably
should be avoided (I'll skip this tangent for now).
Personally I still like the idea of an exists(), because I feel that is how many programmers treat
and use the isset() function - simply because they do use NULL as a valid value, and either
haven't read the manual, or forget the exception that is mentioned on line 1 (something
I've done a couple of times).
Although I realise it will take many years before anyone can start using it.
Craig
On 26 Aug 2015, at 19:44, Rowan Collins <rowan.collins@gmail.com> wrote:
> Craig Francis wrote on 26/08/2015 18:07:
>> I provide examples to help explain that I (and I suspect most developers) default to using
>> isset which works on either.
>>
>> Just because there is a function, which does not exactly roll off the tongue (plus the fun
>> of the needle/haystack ordering issue), does not mean it gets used (even if it is the correct thing
>> to use).
>
>
> That's all very well, but what is the Internals community supposed to do about it? Does
> the documentation need to be improved to point out that there is a better function to use for this
> case?
>
>> I say "or key" because developers use the isset function on both $var and
>> $var['key']... yes, I know they are different, but when you are coding in PHP an isset
>> check is an isset check (well it isn't, because the variable may technically exist).
>>
>> If this is a problem, maybe PHP should raise a notice when isset is used on arrays?
>
>
> It's only a problem in the same way that using file_exists() is a problem when you
> actually wanted the functionality of is_readable() - both functions exist, and it's not the
> language's responsibility to guess which you meant.
>
>
>
>>>> where NULL may be a perfectly valid value.
>>> It's not that NULL isn't a valid value; it's that "doesn't
>>> exist" isn't a meaningful state for a variable. It's like checking if the current
>>> line number is greater than 100, it shouldn't mean anything to the compiled program. See the SO
>>> answer I linked earlier for more thought experiments along these lines.
>>
>> I think you have been spending too much time in C.
>>
>> Most of the PHP code bases I've worked on set variables to NULL at some point (and
>> they are not calling unset, because that isn't the intention).
>
>
> Perhaps my double negative made it unclear, so I will restate: there is nothing wrong with
> setting a variable to NULL. There is also nothing wrong with calling unset() on a plain variable,
> e.g. to make it obvious to readers of the code that this variable should not be used below this
> point.
>
> There IS something wrong with any code which needs to distinguish which of those two things
> happened, at run-time, because such code would be incredibly fragile and hard to follow.
>
> You could, if you wanted, emulate a boolean variable by using $foo=null for true, and
> unset($foo) for false, but why not simply have a boolean variable?
>
> [Incidentally, I know barely any C, but program PHP for a living.]
>
> Regards,
> --
> Rowan Collins
> [IMSoP]
>
> --
> PHP Internals - PHP Runtime Development Mailing List
> To unsubscribe, visit: http://www.php.net/unsub.php
>