php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72081 __get called before __isset
Submitted: 2016-04-22 22:46 UTC Modified: 2016-04-23 14:37 UTC
Votes:1
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: jarnix at jarnix dot com Assigned:
Status: Duplicate Package: Class/Object related
PHP Version: 5.6.20 OS: linux
Private report: No CVE-ID: None
Welcome back! If you're the original bug submitter, here's where you can edit the bug or add additional notes.
If you forgot your password, you can retrieve your password here.
Password:
Status:
Package:
Bug Type:
Summary:
From: jarnix at jarnix dot com
New email:
PHP Version: OS:

 

 [2016-04-22 22:46 UTC] jarnix at jarnix dot com
Description:
------------
I have an object when I override __get and __isset. I try to use __isset but it seems that the __get is called before __isset. It's not the same thing with arrays (I can do isset($someArray['existingParentKey']['notExistingChildKey']) or isset($someArray['notExistingParentKey']['notExistingChildKey']) without problem.

I added multiple examples and comments to show it.

Maybe it's the expected behaviour. The __get should try __iset before trying to get the value, but it doesn't seem logical.

It might be a duplicate of #72056 (__get is called for testing if chained property is set)

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

class Config
{
    
    protected static $data;
    
    public static function init() {
        self::$data = new \StdClass();
        self::$data->parent = new \StdClass();
    }
    
    public function __get($key) {
        return self::$data->$key;
    }
    
    public function __isset($key) {
        return(isset(self::$data->$key));
    }
    
}

$config = new Config();

// prints "is set", as expected
if(isset($config->parent)) {
    echo 'is set' . PHP_EOL;
}
else {
    echo 'not set' . PHP_EOL;
}

// should print "not set" but throws an exception before
if(isset($config->parent->notChild)) {
    echo 'isset' . PHP_EOL;
}
else {
    echo 'not set' . PHP_EOL;
}

// prints "not set"
if(isset($config->notParent)) {
    echo 'is set' . PHP_EOL;
}
else {
    echo 'not set' . PHP_EOL;
}


// should write "not set" but throws an exception before
if(isset($config->notParent->test)) {
    echo 'is set' . PHP_EOL;
}
else {
    echo 'not set' . PHP_EOL;
}


Expected result:
----------------
The __isset should be called recursively before trying to __get the child element.

Actual result:
--------------
An exception is thrown, making the __isset useless.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-22 22:50 UTC] jarnix at jarnix dot com
-Package: PHP Language Specification +Package: Class/Object related
 [2016-04-22 22:50 UTC] jarnix at jarnix dot com
wrong package
 [2016-04-22 22:55 UTC] nikic@php.net
-Status: Open +Status: Duplicate
 [2016-04-22 22:55 UTC] nikic@php.net
Duplicate of #72056, which is already fixed in 7.0.6.
 [2016-04-23 14:26 UTC] jarnix at jarnix dot com
If it's a duplicate and it's fixed in 7.0.6, does it mean it won't be fixed in the 5.6 branch ?
 [2016-04-23 14:26 UTC] jarnix at jarnix dot com
If it's a duplicate and it's fixed in 7.0.6, does it mean it won't be fixed in the 5.6 branch ?
 [2016-04-23 14:37 UTC] nikic@php.net
Correct, there are currently no plans to backport this change to PHP 5.6. It's a pretty subtle behavior difference in an edge-case that was not very relevant before PHP 7.0.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Fri May 09 15:01:27 2025 UTC