Reputation: 20550
given the following code:
$tree = array();
$node =& $tree[];
// imagine tons of code that populates $tree here
how can i entirely delete the ZVAL $node
points to by reference? Is that even possible?
Using unset()
, only the reference is destroyed and not the node in $tree
itself:
unset($node);
print_r($tree);
// outputs:
Array
(
[0] =>
)
I know this is the expected behaviour of unset($reference)
and I also know how the ZVAL refcounter works.
But i really need to delete that node after processing in a specific corner case.
Can i somehow find the correct array index and unset the array element directly like unset($tree[$node_index])
?
Disclaimer: The above example is minified and isolated. Actually i'm modifying a complex parser for a really ugly nested table data structure that is presented as a stream. The code heavily uses pointers as backreferences and i'd like to avoid refactoring the whole code.
Upvotes: 2
Views: 772
Reputation: 437664
If you grab a reference to an array element and unset the reference the array will not be affected at all -- that's just how unset
works, and this behavior is not negotiable.
What you need to do is remember the key of the element in question and unset
directly on the array afterwards:
$tree = array();
$tree[] = 'whatever';
end($tree);
$key = key($tree);
// ...later on...
unset($tree[$key]);
Of course this is extremely ugly and it requires you to keep both $tree
(or a reference to it) and $key
around. You can mitigate this somewhat by packaging the unset operation into an anonymous function -- if there's a good chance you are going to pull the trigger later, the convenience could offset the additional resource consumption:
$tree = array();
$tree[] = 'whatever';
end($tree);
$key = key($tree);
$killThisItem = function() use(&$tree, $key) { unset($tree[$key]); } ;
// ...later on...
$killThisItem();
Upvotes: 2