Sample Code:
<?php
$a = new ArrayObject();
$a['b'] = array('c'=>array('d'));
print_r($a);
unset($a['b']['c']);
print_r($a);
Output
ArrayObject Object
(
[b] => Array
(
[c] => Array
(
[0] => d
)
)
)
ArrayObject Object
(
[b] => Array
(
[c] => Array
(
[0] => d
)
)
)
You notice that $a['b']['c'] is still there, even after unsetting. I would expect $a to have just the one value left (b).
In my actual app, I get the following warning:
Indirect modification of overloaded element of MyClass has no effect
Where MyClass extends ArrayObject. I have a lot of code that depends on being able to unset nested elements like this, so how can I get this to work?
One way to do it
prints:
Would have to think a bit longer for an explanation as to why the syntax you’ve originally used doesn’t remove the element.
EDIT: Explanation of behavior
What’s happening is the call to
unset($a['b']['c']);is translated into:since
$tempis a copy of$ainstead of a reference to it, PHP uses copy-on-write internally and creates a second array where$tempdoesn’t have['b']['c'], but$astill does.ANOTHER EDIT: Reusable Code
So, no matter which way you slice it, seems like trying to overload
function offsetGet($index)to befunction &offsetGet($index)leads to trouble; so here’s the shortest helper method I came up w/ could add it as a static or instance method in a subclass ofArrayObject, whatever floats your boat:So the original code would become
YET ANOTHER EDIT: OO Solution
OK – So I must have been scrambling this morning b/c I found an error in my code, and when revised, we can implement a solution, based on OO.
Just so you know I tried it, extension segfaults..:
Implementing a Decorator on the other hand works like a charm:
Now this code works as desired:
Still have to modify some code though..; I don’t see any way round that.