Bug #62059 [Opn->Csd]: ArrayObject and isset are not friends.
| From: | nikic@php.net | Date: | Sun, 20 Mar 2016 17:19:28 +0000 |
| Subject: | Bug #62059 [Opn->Csd]: ArrayObject and isset are not friends. | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-199966@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=62059&edit=1
ID: 62059
Updated by: nikic@php.net
Reported by: julien at palard dot fr
Summary: ArrayObject and isset are not friends.
-Status: Open
+Status: Closed
Type: Bug
Package: SPL related
Operating System: Linux 2.6.32-5-amd64
PHP Version: Irrelevant
Block user comment: N
Private report: N
New Comment:
Automatic comment on behalf of nikic
Revision: http://git.php.net/?p=php-src.git;a=commit;h=f3309173f916e3c5cf37910975f04310706336b5
Log: Fixed bug #62059
Previous Comments:
------------------------------------------------------------------------
[2015-05-13 13:31:19] contact dot 01834e2c at renegade334 dot me dot uk
This has only been partially fixed.
When isset($ArrayObject['foo']['bar']) is called, Zend doesn't call
spl_array_has_dimension_ex(). Instead, it puts in a call to spl_array_get_dimension_ptr() with
type=BP_VAR_IS. This value of type means that it doesn't generate a notice if 'foo'
isn't a valid index.
However, it is worth pointing out that at a Zend level, the native offsetGet method is never
actually called in this case. However, it IS called if isset() is called on an instance of a child
class, which has overwritten the offsetGet method with a function that calls parent::offsetGet().
Consider the following:
<?php
class MyArrayObject extends ArrayObject {
public function offsetGet($index) {
// ...
return parent::offsetGet($index);
}
}
$ArrayObject = new ArrayObject;
$MyArrayObject = new MyArrayObject;
isset($ArrayObject['foo']['bar']);
isset($MyArrayObject['foo']['bar']);
?>
In the first case, ArrayObject::offsetGet() is NOT actually being called - Zend takes a shortcut by
going straight from spl_array_read_dimension_ex() to spl_array_get_dimension_ptr(), without calling
the offsetGet method.
In the second case, spl_array_read_dimension_ex() detects the presence of the overwritten offsetGet
method, and calls it. This DOES call the native offsetGet method, which didn't happen in the
case before.
The native offsetGet method calls spl_array_read_dimension_ex() again, BUT this time, the call is
made with type=BP_VAR_R (not BP_VAR_IS as before). This means that spl_array_get_dimension_ptr()
DOES generate a notice if the index does not exist.
In other words:
- isset($ArrayObject['foo']['bar']) DOES NOT generate a notice, as the native
offsetGet method is never actually called by Zend.
- isset($MyArrayObject['foo']['bar']) DOES generate a notice, as it specifically
calls the native offsetGet method.
This is inconsistent behaviour, and should be addressed.
$ ~/builds/php7/bin/php --version
PHP 7.0.0-dev (cli) (built: May 13 2015 14:51:36)
Copyright (c) 1997-2015 The PHP Group
Zend Engine v3.0.0-dev, Copyright (c) 1998-2015 Zend Technologies
------------------------------------------------------------------------
[2015-01-10 22:19:16] ajf at ajf dot me
Hey, it's not the ->__isset() magic method that isset() calls for indexes (array access).
__isset() is used for checking property existence. You're probably thinking of
ArrayAccess's ->offsetExists(), which ArrayObject does implement.
Also, this bug isn't really about ArrayObject per se, it's about ArrayAccess's
offsetExists() not working with isset().
------------------------------------------------------------------------
[2014-09-03 13:08:03] php at mandark dot fr
Seems fix in PHP 5.5.16
------------------------------------------------------------------------
[2013-05-23 20:01:54] spneacy at gmail dot com
Confirmed in version 5.4.6
When using version 5.4.9, it appears to have been incidentally (or silently)
fixed.
------------------------------------------------------------------------
[2012-10-23 23:05:33] roberts at x0 dot lv
Confirmed present in 5.3.3-7 and 5.4.7-7, and 5.4.8-1
------------------------------------------------------------------------
The remainder of the comments for this report are too long. To view
the rest of the comments, please view the bug report online at
https://bugs.php.net/bug.php?id=62059
--
Edit this bug report at https://bugs.php.net/bug.php?id=62059&edit=1