Bug #72957 [Ver->Csd]: Null coalescing operator doesn't behave as expected with SimpleXMLElement
| From: | nikic@php.net | Date: | Tue, 30 Aug 2016 11:07:45 +0000 |
| Subject: | Bug #72957 [Ver->Csd]: Null coalescing operator doesn't behave as expected with SimpleXMLElement | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-203676@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=72957&edit=1
ID: 72957
Updated by: nikic@php.net
Reported by: dailywatchdeal at gmail dot com
Summary: Null coalescing operator doesn't behave as expected
with SimpleXMLElement
-Status: Verified
+Status: Closed
Type: Bug
Package: SimpleXML related
Operating System: Ubuntu
PHP Version: 7.0.10
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=bfd4277008d3bda95ff5b418c60d41d50488d33b
Log: Fix bug #72957
Previous Comments:
------------------------------------------------------------------------
[2016-08-29 14:24:51] cmb@php.net
> So does FETCH_OBJ_IS differ for internal and userland code?
It doesn't appear to be so. Consider <https://3v4l.org/PJGqt>. In
either case (SimpleXMLElement and stClass) ZEND_FETCH_OBJ_IS takes
the same code path, and calls zobj->handlers->read_property()[1].
That works as expected for all userland and most internal objects,
but not for SimpleXMLElements.
So it boils down to SimpleXMLElements allowing to read properties,
which they otherwise claim to not exist. At least that is one
possible interpretation. The other would be that the null coalesce
operator would have to be compiled into the same opcodes as the
repective
isset($x) ? $x : $y. Still, I'd find the
SimpleXMLElement inconsistency to be confusing, at best. I can't
assess the impact of changing the behavior, though.
[1] <https://github.com/php/php-src/blob/PHP-7.1.0beta3/Zend/zend_vm_def.h#L2066>
------------------------------------------------------------------------
[2016-08-29 11:18:49] requinix@php.net
I'm being hypocritical: I've said before that $x ?? $y should be equivalent to isset($x) ?
$x : $y, so this really is more of a bug than a request.
As I try to look deeper, this does indeed seem more like a bug - albeit one that may uniquely affect
SimpleXMLElement. I could keep going into this but I don't know enough about the engine to tell
why the same opcodes don't invoke has_property on SimpleXMLElement but do call __isset on
userland classes. I do see that it uses a FETCH_OBJ_IS instead of the ISSET_ISEMPTY_PROP_OBJ jmping
logic that isset() does... So does FETCH_OBJ_IS differ for internal and userland code?
https://3v4l.org/DF8AE/vld#output
I'll bump to Verified but I'm not confident enough in my analysis to go to Analyzed.
@cmb: No doubt that's part of the magic. I'd guess that the idea was to allow code like
foreach ($xml->zero_or_more_elements as $e) {
without having to wrap it all in an isset check. Breaking it would be a BC thing, but I wonder how
often that magic is actually relied upon...
The inconsistency is a bit of a bother. Has anyone else ever noticed it? With a quick search I
haven't found any bug reports mentioning it. Maybe it's worth breaking?
------------------------------------------------------------------------
[2016-08-29 10:24:49] cmb@php.net
> That's because $xml->elem2 exists and isn't null.
If it is set and it is not NULL, shouldn't isset() return TRUE?
The current behavior (<https://3v4l.org/1NYAA>) looks
like a bug
to me.
------------------------------------------------------------------------
[2016-08-29 08:51:34] dailywatchdeal at gmail dot com
According to the docs, ?? is the same as isset, just a different syntax. Maybe the documentation
should be updated?
------------------------------------------------------------------------
[2016-08-28 20:14:55] requinix@php.net
That's because $xml->elem2 exists and isn't null. isset works differently.
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=72957
--
Edit this bug report at https://bugs.php.net/bug.php?id=72957&edit=1