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 Add Comment Developer Edit
Anyone can comment on a bug. Have a simpler test case? Does it work for you on a different platform? Let us know!
Just going to say 'Me too!'? Don't clutter the database with that please !
Your email address:
MUST BE VALID
Solve the problem:
18 - 2 = ?
Subscribe to this entry?

 
 [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

Add a Patch

Pull Requests

Add a Pull Request

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: Sat Apr 20 00:01:27 2024 UTC