给定以下代码:
$tree = array();
$node =& $tree[];
// imagine tons of code that populates $tree here
如何通过引用将ZVAL $node
点完全删除到?这可能吗?
使用unset()
,只有引用被破坏,而不是$tree
中的节点本身:
unset($node);
print_r($tree);
// outputs:
Array
(
[0] =>
)
我知道这是unset($reference)
的预期行为,我也知道ZVAL refcounter是如何工作的。
但我真的需要在处理完一个特定的角落案例后删除那个节点。
我能以某种方式找到正确的数组索引并像unset($tree[$node_index])
一样直接取消设置数组元素吗?
免责声明:上面的例子是缩小和孤立的。实际上,我正在修改一个复杂的解析器,用于一个非常丑陋的嵌套表数据结构,该结构以流的形式呈现。代码大量使用指针作为反向引用,我希望避免重构整个代码。
如果获取对数组元素的引用并取消设置该引用,则数组将不会受到任何影响——unset
就是这样工作的,并且这种行为是不可协商的。
你需要做的是记住有问题的元素的键,然后直接在数组上记住unset
:
$tree = array();
$tree[] = 'whatever';
end($tree);
$key = key($tree);
// ...later on...
unset($tree[$key]);
当然,这是非常丑陋的,它要求您同时保留$tree
(或对它的引用)和$key
。您可以通过将unset操作打包到一个匿名函数中来缓解这种情况——如果您稍后很有可能触发,那么这种便利性可以抵消额外的资源消耗:
$tree = array();
$tree[] = 'whatever';
end($tree);
$key = key($tree);
$killThisItem = function() use(&$tree, $key) { unset($tree[$key]); } ;
// ...later on...
$killThisItem();