php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72117 Magic __isset applied wrong
Submitted: 2016-04-28 09:39 UTC Modified: 2016-04-28 10:06 UTC
From: rullzer at owncloud dot com Assigned:
Status: Not a bug Package: Class/Object related
PHP Version: Next Minor Version OS: Linux
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: rullzer at owncloud dot com
New email:
PHP Version: OS:

 

 [2016-04-28 09:39 UTC] rullzer at owncloud dot com
Description:
------------
The code example makes is pretty clear.

When using the magic __get method and __isset method in 7.0.6 things break. The __isset is called with the wrong argument.

Tested this the 7.0.6 tag.

Test script:
---------------
https://3v4l.org/r9QFk

Expected result:
----------------
The argument to isset is first evaluated as much as possible and only then is isset called.

Actual result:
--------------
Isset seems to be greedy in 7.0.6 and call with the first argument it can find. Which can fail.

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-28 10:02 UTC] bwoebi@php.net
-Status: Open +Status: Not a bug
 [2016-04-28 10:02 UTC] bwoebi@php.net
This is a bugfix in 7.0.6, __isset() never had been called there even if it should have been:
https://3v4l.org/J0Lkk

To check if something is isset(), you generally need to check every dimension.
Is $this->a set? No it isn't (according to __isset()). isset() thus returns false.
If it were set, then isset() checks the next dimension and calls __get() to get the next dimension.

This is necessary to avoid failures in legitimate cases like (https://3v4l.org/r8U7T):

class A {
    private $foo = ["a" => [1, 2, 3]];

    function __get($a) {
        if (isset($this->foo[$a])) {
            return $this->foo[$a];
        }
        throw new Exception("Invalid key accessed! Check with isset() first!");
    }

    function __isset($a) {
        return isset($this->foo[$a]);
    }
}

$obj = new A;
var_dump(isset($obj->a[1]));
var_dump(isset($obj->b[1])); // exception in versions before 7.0.6
 [2016-04-28 10:06 UTC] bwoebi@php.net
See also bug #69659
 [2016-05-16 15:02 UTC] koubel at seznam dot cz
Maybe it's duplicate of https://bugs.php.net/bug.php?id=72223,

It seems that you make the BC break in patch release, which can be relative big problem in migration from PHP 5.6 to PHP 7.0. It's necessary to document this in migration guide at least.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Dec 22 06:01:30 2024 UTC