Bug #75831 [Com]: Coalesce operator ?? never uses the default isset() handler

From: Date: Sun, 21 Jan 2018 17:23:44 +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-213642@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:         timok at ya dot ru
 Reported by:        nobots dot nospam at example dot org
 Summary:            Coalesce operator ?? never uses the default isset()
                     handler
 Status:             Open
 Type:               Bug
 Package:            *General Issues
 PHP Version:        7.2.1
 Block user comment: N
 Private report:     N

 New Comment:

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


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


Thread (5 messages)

« previous php.bugs (#213642) next »