Req->Bug #72957 [Opn->Ver]: Null coalescing operator doesn't behave as expected with SimpleXMLElement

From: Date: Mon, 29 Aug 2016 11:18:53 +0000
Subject: Req->Bug #72957 [Opn->Ver]: Null coalescing operator doesn't behave as expected with SimpleXMLElement
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-203647@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:         requinix@php.net
 Reported by:        dailywatchdeal at gmail dot com
 Summary:            Null coalescing operator doesn't behave as expected
                     with SimpleXMLElement
-Status:             Open
+Status:             Verified
-Type:               Feature/Change Request
+Type:               Bug
 Package:            SimpleXML related
 Operating System:   Ubuntu
 PHP Version:        7.0.10
 Block user comment: N
 Private report:     N

 New Comment:

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?


Previous Comments:
------------------------------------------------------------------------
[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.

------------------------------------------------------------------------
[2016-08-28 18:42:20] dailywatchdeal at gmail dot com

Description:
------------
According to the docs, the ?? operator checks if the 1st operand exists and is not null. In other
words, it's equivalent to isset.
When used to check if a SimpleXMLElement node exists, it doesn't work.


Test script:
---------------
<?php

$xml = new SimpleXMLElement('<root><elem>Text</elem></root>');

echo 'elem2 is: ' . ($xml->elem2 ?? 'backup string');
echo 'elem2 is: ' . (isset($xml->elem2) ? $xml->elem2 : 'backup string');


Expected result:
----------------
elem2 is: backup string
elem2 is: backup string

Actual result:
--------------
elem2 is: 
elem2 is: backup string


------------------------------------------------------------------------



--
Edit this bug report at https://bugs.php.net/bug.php?id=72957&edit=1


Thread (7 messages)

« previous php.bugs (#203647) next »