Edit report at http://bugs.php.net/bug.php?id=52861&edit=1
ID: 52861
Comment by: auke at muze dot nl
Reported by: mep_eisen at web dot de
Summary: unset failes with ArrayObject and deep arrays
Status: Open
Type: Bug
Package: SPL related
Operating System: Windows Vista 64
PHP Version: 5.3.3
Block user comment: N
Private report: N
New Comment:
I found a workaround for the problem that suddenly the parent object has
any
property you try to access and has it filled with the previously set
array.
If the containing object has its own __get() method which always returns
NULL,
the object is safe again. So this code works as expected:
class IWouldLikeToPointOutABug {
function __get( $name ) {
return NULL;
}
}
$buggy = new IWouldLikeToPointOutABug();
$buggy->bug = new ArrayObject( );
$buggy->bug['foo']['bar'] = true;
echo "This looks normal\r\n";
var_dump( $buggy );
echo "This should be NULL\r\n";
var_dump( $buggy->thisIsNotHere );
One drawback is that you cannot assign properties by reference anymore
because
you're now using the __get() overloading method.
This does not fix the original bug where unsetting fails.
BTW. Our original workaround involved creating our own arrayobject by
implementing all the array interfaces, but that will not work either.
When you
do this:
$arrayobject['unsetkey']['key'] = $value;
The offsetSet method is never called for 'unsetKey', just the offsetGet.
So
there is no way to implement the correct behaviour.
Previous Comments:
------------------------------------------------------------------------
[2011-01-05 18:51:51] auke at muze dot nl
It's worse than this, ArrayObject gets confused on where to put the data
and mangles any containing object:
test script:
class IWouldLikeToPointOutABug {
}
$buggy = new IWouldLikeToPointOutABug();
$buggy->bug = new ArrayObject( );
$buggy->bug['foo']['bar'] = true;
echo "This looks normal\r\n";
var_dump( $buggy );
echo "This should be NULL\r\n";
var_dump( $buggy->thisIsNotHere );
Results in:
This looks normal
object(IWouldLikeToPointOutABug)#1 (1) {
["bug"]=>
object(ArrayObject)#2 (0) {
}
}
This should be NULL
array(1) {
["bar"]=>
bool(true)
}
------------------------------------------------------------------------
[2010-09-16 17:23:11] mep_eisen at web dot de
Description:
------------
Using deep arrays unset itself or ArrayObject misbehaves. It silently
does nothing.
The problem lies in iteration 3 that mixes ArrayObject and classic
arrays.
Test script:
---------------
echo "iteration1\n";
$arr = new ArrayObject();
$arr['foo'] = new ArrayObject();
$arr['foo']['bar'] = true;
unset($arr['foo']['bar']);
var_dump($arr);
echo "iteration2\n";
$arr = array();
$arr['foo']['bar'] = true;
unset($arr['foo']['bar']);
var_dump($arr);
echo "iteration3\n";
$arr = new ArrayObject();
$arr['foo']['bar'] = true;
unset($arr['foo']['bar']);
var_dump($arr);
Expected result:
----------------
iteration1
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["foo"]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
}
}
iteration2
array(1) {
["foo"]=>
array(0) {
}
}
iteration3
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["foo"]=>
array(0) {
}
}
}
Actual result:
--------------
iteration1
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["foo"]=>
object(ArrayObject)#2 (1) {
["storage":"ArrayObject":private]=>
array(0) {
}
}
}
}
iteration2
array(1) {
["foo"]=>
array(0) {
}
}
iteration3
object(ArrayObject)#1 (1) {
["storage":"ArrayObject":private]=>
array(1) {
["foo"]=>
array(1) {
["bar"]=>
bool(true)
}
}
}
------------------------------------------------------------------------
--
Edit this bug report at http://bugs.php.net/bug.php?id=52861&edit=1