可以在PHP中取消引用引用吗?

可以在PHP中取消引用引用吗?,php,Php,我使用一个数组作为堆栈来存储通过树的路径。每个元素都指向树中的一个节点,我想弹出最后一个元素,然后将该元素引用的对象设置为null 基本上: $node = array_pop($path); *$node = null; 假设PHP和C-ish语言一样有一个“*”操作符。现在,我有一个丑陋的解决方案,从父节点开始,记住我取了哪个子节点,然后将其设置为null,如中所示: if($goLeft) { $parent->left = null; } else { $pare

我使用一个数组作为堆栈来存储通过树的路径。每个元素都指向树中的一个节点,我想弹出最后一个元素,然后将该元素引用的对象设置为null

基本上:

$node = array_pop($path);
*$node = null;
假设PHP和C-ish语言一样有一个“*”操作符。现在,我有一个丑陋的解决方案,从父节点开始,记住我取了哪个子节点,然后将其设置为null,如中所示:

if($goLeft) {
    $parent->left = null;
} else {
    $parent->right = null;
}
我说这很难看,因为包含路径的数组是由树类中的一个公共函数创建的。我想公开直接在树路径中的节点上工作的能力,而不公开解决PHP中的特性(功能?)的实现细节。ATM我需要在返回值中包含一个布尔值($goLeft在本例中),这样我就可以解决无法取消引用的问题

这是我第二次遇到这个问题,所以如果有人知道我可以做类似于第一段代码的事情,请分享

(编辑)

在对&’和数组的许多排列进行了实验之后,发现基本问题是我误解了错误的原因

我试过了

$a = ($x > $y) ? &$foo[$bar] : $blah;
并得到“语法错误,意外的'&'”。我解释这意味着问题是在
$foo[$bar]
上使用了&-运算符。事实证明凶手是?-接线员

if($x > $y) {
    $a = &$foo[$bar];
} else {
    $a = null;
}
很好用。因此,我开始了一场白费力气的追逐,为一个根本不存在的问题寻找解决办法。只要我不打破&’的链条,PHP就会做我想做的事情,即对变量引用的对象(而不是变量本身)进行操作。范例

让我搞砸的是,我认为对象无论如何都是通过引用传递的(这是错误的),所以如果表达式解析为对象,我认为&是不必要的。我的意思是:

class A {
    public $b;
}

class B {}

$a = new A;
$a->b = new B; 

$c1 = $a->b; 
$c2 = &$a->b;

$c1 = 42; // Merely assigns 42 to $c1
$c2 = 42; // Assigns 42 to $a->b

事实证明,这个确切的问题是在。但愿我第一次读到它的时候,它就沉下去了

只需不分配
数组\u pop()
返回值即可

php > $test = array(1, 2, 3);
php > $test2 = array(0 => &$test[0], 1 => &$test[1], 2 => &$test[2]);
php > array_pop($test2);
php > var_dump($test);
array(3) {
  [0]=>
  &int(1)
  [1]=>
  &int(2)
  [2]=>
  int(3)
}
php > var_dump($test2);
array(2) {
  [0]=>
  &int(1)
  [1]=>
  &int(2)
}

我希望我能记得我在哪里读到这篇文章,但是PHP通过维护对给定对象的引用计数器来工作。您有一些对象(例如
)引用了一些节点。使用
array\u pop
时,将返回对节点对象的引用(即创建一个附加引用),但原始引用仍然存在。当
取消设置
弹出的引用时,该引用将被销毁,但原始对象不会被销毁,因为
仍然具有该引用。释放该对象内存的唯一方法是让
Tree
亲自销毁它(这似乎是您在第二个代码块中所做的)

PHP似乎没有任何强制内存释放或垃圾回收的方法,因此除非您小心地处理引用,否则您将陷入困境

这是不可能的


顺便说一句,我仍然对你想做什么感到困惑。Rocket的解释很有帮助,但是什么是
$path
,它与第二个块有什么关系?

非常有趣的问题!我可能已经找到了一个解决方法:如果使用对象引用填充数组,使用
&
操作符,可以通过将该数组值设置为
NULL
来销毁原始对象。您必须直接对数组进行操作,而不是使用
array\u pop
返回的变量。之后,可以弹出数组以释放该位置(该位置将包含一个
NULL
值)

这就是我的意思(基于火箭的代码):


php中的引用允许您更改对象。

我不确定,这是您想要的,但您可以使用
unset($parent->left)
而不是
$parent->left=null@PLB:我想你的意思是
取消链接
,而不是
取消链接
@Rocket当然,我知道。我很累。我不明白你想做什么。您希望(如果存在)*$node=null做什么?也许你可以展示你的树类来帮助我们理解对于那些不理解的人,
$path
是一个引用数组(指向对象)。他想通过引用取消设置原始对象<代码>$a=(对象)'a'$b=阵列($a)$c=数组_pop($b);echo$a->scalar;//'一个“
(是的,该代码有效:)。他只想使用
$c
$a
设置为空。不完全是这样。他想要的是取消设置“原始”对象(
$test[2]
)。为什么
array\u pop
的返回值很重要?您正在以任何方式修改
$test2
。嗯。。。从描述中很难看出这一点。:)我认为我最初的问题过于具体。我使用堆栈,或者试图将某些内容设置为null,这实际上并不重要。我需要更好地解释我自己。假设我有一个变量,它包含对某物的引用——一个对象,另一个变量,它不重要。示例:
a=&b
现在我想对
$a
引用的对象执行一个操作,在本例中是
$b
。也许我想将
$b
设置为null,字符串“alice”,或者设置为另一个对象。没关系。不管怎么说,这就是我想要实现的。@kahulio这有点难以解释。基本上,
$a=&$b
创建一个从
$a
$b
的符号表别名。也就是说,您对
$a
所做的任何操作都会直接影响
$b
。如果
$b
是对象,则
$a=$b
将对象引用从
$b
复制到
$a
。对对象
$a
的操作与对对象
$b
的操作具有相同的效果,但它是一个单独的符号表条目。如果您向
$a
$a='blah';
)写入代码,它根本不会影响
$b
<代码>数组\u pop不返回引用
php > $test = array(1, 2, 3);
php > $test2 = array(0 => &$test[0], 1 => &$test[1], 2 => &$test[2]);
php > array_pop($test2);
php > var_dump($test);
array(3) {
  [0]=>
  &int(1)
  [1]=>
  &int(2)
  [2]=>
  int(3)
}
php > var_dump($test2);
array(2) {
  [0]=>
  &int(1)
  [1]=>
  &int(2)
}
$a=(object)'a';
$b=array(&$a);
$b[0] = NULL;
// array still contains an element
array_pop($b);
// now array is empty
var_dump($a); // NULL
$one = 1;
$two = 2;
$array = array(&$one, &$two);

// magic
end($array);
$array[key($array)] = NULL;

var_dump($two);
// NULL