Req #69659 [NEW]: ArrayAccess, isset() and the offsetExists method

From: 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

« previous php.bugs (#192746) next »