One way to do it
<?php $a = new ArrayObject(); $a['b'] = array('c' => array('d')); $d =& $a['b']; unset($d['c']); print_r($a['b']);
prints:
Array ( )
Think a little longer to explain why the syntax you originally used does not remove the element.
EDIT: Explanation of Behavior
What happens is the unset($a['b']['c']); call unset($a['b']['c']); converted to:
$temp = $a->offsetGet('b'); unset($temp['c']);
since $temp is a copy of $a instead of referencing it, PHP uses an internal copy-on-write copy and creates a second array where $temp does not have ['b']['c'] , but $a still does.
OTHER EDITING: reusable code
So, no matter how you function offsetGet($index) it, it seems like trying to overload function offsetGet($index) as function &offsetGet($index) causing trouble; so here is the shortest helper method that I came up with that could add it as a static or instance method to a subclass of ArrayObject , regardless of what your boat floats:
function unsetNested(ArrayObject $oArrayObject, $sIndex, $sNestedIndex) { if(!$oArrayObject->offSetExists($sIndex)) return; $aValue =& $oArrayObject[$sIndex]; if(!array_key_exists($sNestedIndex, $aValue)) return; unset($aValue[$sNestedIndex]); }
So, the source code will become
$a = new ArrayObject(); $a['b'] = array('c' => array('d')); // instead of unset($a['b']['c']); unsetNested($a, 'b', 'c'); print_r($a['b']);
GIVE ANOTHER CHANGE: OO Solution
OK - So, I must have scrambled b / c this morning. I found an error in my code, and when it was changed, we can implement an OO based solution.
Just so you know what I tried, the segfaults .. extension:
/// XXX This does not work, posted for illustration only class BadMoxuneArrayObject extends ArrayObject { public function &offsetGet($index) { $var =& $this[$index]; return $var; } }
The decorator's implementation, on the other hand, works like a charm:
class MoxuneArrayObject implements IteratorAggregate, ArrayAccess, Serializable, Countable { private $_oArrayObject; // Decorated ArrayObject instance public function __construct($mInput=null, $iFlags=0, $sIteratorClass='') { if($mInput === null) $mInput = array(); if($sIteratorClass === '') $this->_oArrayObject = new ArrayObject($mInput, $iFlags); else $this->_oArrayObject = new ArrayObject($mInput, $iFlags, $sIteratorClass); } // ----------------------------------------- // override offsetGet to return by reference // ----------------------------------------- public function &offsetGet($index) { $var =& $this->_oArrayObject[$index]; return $var; } // ------------------------------------------------------------ // everything else is passed through to the wrapped ArrayObject // ------------------------------------------------------------ public function append($value) { return $this->_oArrayObject->append($value); } public function asort() { return $this->_oArrayObject->asort(); } public function count() { return $this->_oArrayObject->count(); } public function exchangeArray($mInput) { return $this->_oArrayObject->exchangeArray($mInput); } public function getArrayCopy() { return $this->_oArrayObject->getArrayCopy(); } public function getFlags() { return $this->_oArrayObject->getFlags(); } public function getIterator() { return $this->_oArrayObject->getIterator(); } public function getIteratorClass() { return $this->_oArrayObject->getIteratorClass(); } public function ksort() { return $this->_oArrayObject->ksort(); } public function natcassesort() { return $this->_oArrayObject->natcassesort(); } public function offsetExists($index) { return $this->_oArrayObject->offsetExists($index); } public function offsetSet($index, $value) { return $this->_oArrayObject->offsetSet($index, $value); } public function offsetUnset($index) { return $this->_oArrayObject->offsetUnset($index); } public function serialize() { return $this->_oArrayObject->serialize(); } public function setFlags($iFlags) { return $this->_oArrayObject->setFlags($iFlags); } public function setIteratorClass($iterator_class) { return $this->_oArrayObject->setIteratorClass($iterator_class); } public function uasort($cmp_function) { return $this->_oArrayObject->uasort($cmp_function); } public function uksort($cmp_function) { return $this->_oArrayObject->uksort($cmp_function); } public function unserialize($serialized) { return $this->_oArrayObject->unserialize($serialized); } }
Now this code works as desired:
$a = new MoxuneArrayObject(); $a['b'] = array('c' => array('d')); unset($a['b']['c']); var_dump($a);
You still need to modify the code, though ..; I see no way around this.