Kaii
Kaii

Reputation: 20550

delete variable by reference

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

Answers (1)

Jon
Jon

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

Related Questions