Bug #72408 [Csd->Nab]: Coalescing operator on classes with overridden __get() method and NOT __isset()
| From: | requinix@php.net | Date: | Wed, 15 Jun 2016 12:29:55 +0000 |
| Subject: | Bug #72408 [Csd->Nab]: Coalescing operator on classes with overridden __get() method and NOT __isset() | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-201649@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72408&edit=1
ID: 72408
Updated by: requinix@php.net
Reported by: kostasxx at gmail dot com
Summary: Coalescing operator on classes with overridden
__get() method and NOT __isset()
-Status: Closed
+Status: Not a bug
Type: Bug
Package: Scripting Engine problem
Operating System: Linux 4.1.13
PHP Version: 7.0.7
Block user comment: N
Private report: N
Previous Comments:
------------------------------------------------------------------------
[2016-06-15 11:56:48] kostasxx at gmail dot com
Now it makes sense. Since the parameter does not exist, the __get() is triggered.
Thanks for the explanation and sorry for the trouble :).
I will mark the issue as closed.
------------------------------------------------------------------------
[2016-06-15 11:50:27] requinix@php.net
Which it does for both tests. Your expected results are that it should say "value1" for
the first test, thus invoking __get, but not try to do the same for the second. That's
inconsistent.
So you mean to say that both of them should show "default", right? Neither of the tests
should call __get because $attribute1 and 2 are not actually defined.
However,
Like I said in the other bug report, ($x??$y) is equivalent to (isset($x)?$x:$y).
So in this case
var_dump($coal->attribute1 ?? 'default');
should be the same as
var_dump(isset($coal->attribute1) ? $coal->attribute1 : 'default');
but without the second trip to ->attribute1.
Since your class did not implement __isset, doing "$coal->attribute1" will call __get.
That's how it is supposed to work. Because the very existence of __get means that PHP should
not look only at properties defined directly on the instance to determine values.
Make sense?
------------------------------------------------------------------------
[2016-06-15 11:40:24] kostasxx at gmail dot com
Based on RFC, the use of coalescing operator should be equal to isset() and is based to the given
example:
// Fetches the request parameter user and results in 'nobody' if it doesn't exist
$username = $_GET['user'] ?? 'nobody';
// equivalent to: $username = isset($_GET['user']) ? $_GET['user'] :
'nobody';
taken from here https://wiki.php.net/rfc/isset_ternary.
So if you see in the updated code here https://3v4l.org/VUCFF,
that isn't happening.
It bypass isset() and goes to __get() directly.
------------------------------------------------------------------------
[2016-06-15 11:33:26] requinix@php.net
Why is the first test supposed to call __get but the second should not? Neither $attribute1 nor
$attribute2 exist so the behavior should be the same for both.
------------------------------------------------------------------------
[2016-06-15 07:27:17] kostasxx at gmail dot com
Description:
------------
When __get() method is overridden in a class and NOT the __isset(), when the null coalescing
operator is used, the __get() is triggered instead of native isset().
This issue is related to https://bugs.php.net/bug.php?id=71359
Test script:
---------------
https://3v4l.org/RMS3W
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=72408&edit=1