Req #69659 [NEW]: ArrayAccess, isset() and the offsetExists method
| From: | contact dot 01834e2c at renegade334 dot me dot uk | Date: | Tue, 19 May 2015 07:48:03 +0000 |
| Subject: | Req #69659 [NEW]: ArrayAccess, isset() and the offsetExists method | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-192746@lists.php.net to get a copy of this message | ||
From: contact dot 01834e2c at renegade334 dot me dot uk
Operating system: Ubuntu 14.04.2 (Linux 3.13.0-52)
PHP version: master-Git-2015-05-19 (Git)
Package: SPL related
Bug Type: Feature/Change Request
Bug description:ArrayAccess, isset() and the offsetExists method
Description:
------------
Calling isset() or empty() on a dimension of an object that implements
ArrayAccess results in the offsetExists method being called.
When calling isset() or empty() on a subdimension of a dimension of that
object, only the offsetGet method is called, not the offsetExists
method. This is inconsistent, undocumented, and often results in
undefined index notices being raised.
Instead, when isset() or empty() is called on a subdimension of an
object implementing ArrayAccess, the offsetExists method should first be
called to check if the dimension exists. If the dimension does not
exist, then offsetGet should not be called.
This could possibly be implemented at the level of
zend_std_read_dimension() by calling and checking the "offsetexists"
method if type==BP_VAR_IS.
This was previously raised several years ago as #41727. At the time, it
was deemed WONTFIX, although the discussion seemed to miss the point
somewhat. I think the issue should be revisited, not least because the
lack of consistency leads to some interesting quirks elsewhere.
For example, SPL's ArrayObject class, which 'implements' ArrayAccess
internally, will also not call offsetExists when executing
isset($obj['foo']['bar']). However, while the native "get dimension"
handler detects the BP_VAR_IS type and will not throw an invalid index
error in this case, calling parent::offsetGet() from an overridden
offsetGet method *will* result in invalid index errors being thrown.
This was reported under #62059.
Test script:
---------------
https://gist.github.com/Renegade334/2415ec56367ff937c407
Expected result:
----------------
renegade@ochre:~$ builds/php7/bin/php test.php
* Calling isset($obj['foo'])...
offsetExists('foo')
bool(false)
* Calling isset($obj['foo']['bar'])...
offsetExists('foo')
bool(false)
* Setting offset...
offsetSet('foo', NULL)
* Calling isset($obj['foo']['bar'])...
offsetExists('foo')
offsetGet('foo')
bool(false)
Actual result:
--------------
renegade@ochre:~$ builds/php7/bin/php test.php
* Calling isset($obj['foo'])...
offsetExists('foo')
bool(false)
* Calling isset($obj['foo']['bar'])...
offsetGet('foo')
Notice: Undefined index: foo in /home/renegade/test.php on line 14
bool(false)
* Setting offset...
offsetSet('foo', NULL)
* Calling isset($obj['foo']['bar'])...
offsetGet('foo')
bool(false)
--
Edit bug report at https://bugs.php.net/bug.php?id=69659&edit=1
--
Try a snapshot (PHP 5.4): https://bugs.php.net/fix.php?id=69659&r=trysnapshot54
Try a snapshot (PHP 5.5): https://bugs.php.net/fix.php?id=69659&r=trysnapshot55
Try a snapshot (trunk): https://bugs.php.net/fix.php?id=69659&r=trysnapshottrunk
Fixed in SVN: https://bugs.php.net/fix.php?id=69659&r=fixed
Fixed in release: https://bugs.php.net/fix.php?id=69659&r=alreadyfixed
Need backtrace: https://bugs.php.net/fix.php?id=69659&r=needtrace
Need Reproduce Script: https://bugs.php.net/fix.php?id=69659&r=needscript
Try newer version: https://bugs.php.net/fix.php?id=69659&r=oldversion
Not developer issue: https://bugs.php.net/fix.php?id=69659&r=support
Expected behavior: https://bugs.php.net/fix.php?id=69659&r=notwrong
Not enough info: https://bugs.php.net/fix.php?id=69659&r=notenoughinfo
Submitted twice: https://bugs.php.net/fix.php?id=69659&r=submittedtwice
register_globals: https://bugs.php.net/fix.php?id=69659&r=globals
PHP 4 support discontinued: https://bugs.php.net/fix.php?id=69659&r=php4
Daylight Savings: https://bugs.php.net/fix.php?id=69659&r=dst
IIS Stability: https://bugs.php.net/fix.php?id=69659&r=isapi
Install GNU Sed: https://bugs.php.net/fix.php?id=69659&r=gnused
Floating point limitations: https://bugs.php.net/fix.php?id=69659&r=float
No Zend Extensions: https://bugs.php.net/fix.php?id=69659&r=nozend
MySQL Configuration Error: https://bugs.php.net/fix.php?id=69659&r=mysqlcfg