Bug #75831 [Com]: Coalesce operator ?? never uses the default isset() handler
| From: | michael dot vorisek at email dot cz | Date: | Thu, 23 Apr 2020 09:21:14 +0000 |
| Subject: | Bug #75831 [Com]: Coalesce operator ?? never uses the default isset() handler | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-226736@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=75831&edit=1
ID: 75831
Comment by: michael dot vorisek at email dot cz
Reported by: nobots dot nospam at example dot org
Summary: Coalesce operator ?? never uses the default isset()
handler
Status: Assigned
Type: Bug
Package: *General Issues
PHP Version: 7.2.1
Assigned To: nikic
Block user comment: N
Private report: N
New Comment:
Is this expected to be fixed soon - and backported or at least in PHP 8.0?
Previous Comments:
------------------------------------------------------------------------
[2019-01-25 16:24:46] nikic@php.net
I agree with the original reporter that this is a bug. $foo->bar ?? $baz should behave the same
way as isset($foo->bar) ? $foo->bar : $baz, and in this case it does not.
https://3v4l.org/UI13h
------------------------------------------------------------------------
[2018-01-21 17:23:41] timok at ya dot ru
Imho, this is not a bug, but quite expected and correct behavior.
You define a handler to get inaccessible properties (__get), then it is called whenever you try to
access an inaccessible property, including NULL coalesce operator. If object has a property check
method (__isset), then it is called before __get. So, the code
var_dump($bar->foo ?? "qux"); // works now, without errors...
- is equivalent to the following:
var_dump(isset($bar->foo) ? $bar->foo : "qux"); // also works without errors: https://3v4l.org/4EPXm
- http://php.net/manual/en/language.operators.comparison.php#language.operators.comparison.coalesce
- https://wiki.php.net/rfc/isset_ternary
------------------------------------------------------------------------
[2018-01-17 11:44:22] nobots dot nospam at example dot org
Description:
------------
The coalesce operator calls __get(prop) directly without testing isset($obj->prop) first.
It only calls isset($obj->prop) if there is an explicit user-defined __isset() handler.
Test script:
---------------
class Bar{
function __get($a){
throw new Error("no prop error\n");
}
}
$bar = new Bar;
try{
var_dump($bar->foo ?? "qux"); // error...
} catch(Throwable $e){ echo $e->getMessage(); }
var_dump(isset($bar->foo)); // ...but this works fine
Expected result:
----------------
class Bar{
function __isset($a){
return isset($this->{$a});
// I shouldn't be forced to implement this,
// since it looks exactly like the default isset() handler
}
function __get($a){
throw new Error("no prop error\n");
}
}
$bar = new Bar;
var_dump($bar->foo ?? "qux"); // works now, without errors...
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=75831&edit=1