php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #72132 isset() sometimes returns FALSE when TRUE is expected
Submitted: 2016-04-30 10:25 UTC Modified: 2016-04-30 19:22 UTC
From: holger dot schletz at web dot de Assigned:
Status: Not a bug Package: Arrays related
PHP Version: 7.0.6 OS: Arch Linux, Kernel 4.5.1-1-ARCH
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: holger dot schletz at web dot de
New email:
PHP Version: OS:

 

 [2016-04-30 10:25 UTC] holger dot schletz at web dot de
Description:
------------
This seems to be a regression with PHP 7.0.6. The problem does not occur when I downgrade to 7.0.5.

The problem is difficult to reproduce. The test script below will most likely behave correctly, but in some very specific context, a similar case will fail, and the failure is reproducible then.


Test script:
---------------
$var['a']['b'] = 'c';
var_dump($var['a']['b']);
var_dump(isset($var['a']['b']));


Expected result:
----------------
string(1) "c"
bool(true)


Actual result:
--------------
string(1) "c"
bool(false)


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2016-04-30 10:38 UTC] nikic@php.net
-Status: Open +Status: Not a bug
 [2016-04-30 10:38 UTC] nikic@php.net
The issue you are (very likely) hitting, is that starting with PHP 7.0.6 __isset() and offsetExists() will be called for each access level in the expression. So in isset($var['a']['b']), if $var is an ArrayAccess object, you will now see a call to offsetExists($var, 'a'), where none occurred previously. If you don't have a correct offsetExists() implementation, this may lead to the described result.
 [2016-04-30 11:05 UTC] holger dot schletz at web dot de
You are right! I didn't realize that I was working with an ArrayObject instead of a real array. In my case, it was a PHPUnit mock object where the offsetSet method was not stubbed because it didn't have to before. Adding a stub fixed it.

The change might break a lot of edge cases that got away with the previous behavior - mock objects that did not have to deal with those PHP internals before being a not too uncommon case. Could this possible BC break be pointed out in the changelog?
 [2016-04-30 19:22 UTC] holger dot schletz at web dot de
While the error cause is definitely on the application side, the observed behavior is inconsistent. As a future improvement, what about checking the offsetExists() result and generating at least a warning if it is not a boolean? While validating correctness of the result is out of PHP's scope, this would at least ensure that SOMETHING is implemented.
 
PHP Copyright © 2001-2025 The PHP Group
All rights reserved.
Last updated: Sat Jul 12 05:01:33 2025 UTC