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

From: Date: Sun, 20 Mar 2016 12:57:00 +0000
Subject: Req #69659 [Opn]: ArrayAccess, isset() and the offsetExists method
References: 1  Groups: php.bugs 
Request: Send a blank email to php-bugs+get-199961@lists.php.net to get a copy of this message
Edit report at https://bugs.php.net/bug.php?id=69659&edit=1 ID: 69659 Updated by: nikic@php.net Reported by: contact dot 01834e2c at renegade334 dot me dot uk Summary: ArrayAccess, isset() and the offsetExists method Status: Open Type: Feature/Change Request Package: SPL related Operating System: Ubuntu 14.04.2 (Linux 3.13.0-52) PHP Version: master-Git-2015-05-19 (Git) Block user comment: N Private report: N New Comment: Mostly fixed by https://github.com/php/php-src/commit/a175aa9dcaed5e295d015ff73c663e06c2335155. ArrayObject may need additional modifications. Previous Comments: ------------------------------------------------------------------------ [2015-05-19 07:48:02] contact dot 01834e2c at renegade334 dot me dot uk 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 this bug report at https://bugs.php.net/bug.php?id=69659&edit=1

« previous php.bugs (#199961) next »