You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP对象引用疑问:为何countNode赋值不改变外部引用而remove可修改对象

理解PHP中对象引用与变量赋值的区别

你这个困惑的核心,其实是没搞清楚PHP里变量持有对象引用和变量本身是引用的区别,咱们一步步拆解:

先搞懂PHP对象的"引用"到底是什么

PHP里的变量并不是直接存储对象本身,而是存一个指向对象的标识符(可以理解为对象的"地址牌")。当你把对象赋值给变量、或者传递给函数时,传递的是这个标识符的副本——也就是说,函数里的参数变量和外部的变量,都拿着指向同一个对象的"地址牌",但它们是两个完全独立的变量。

为什么remove函数能修改链表结构?

看你的remove函数代码:

function remove(Node $node) {
    $next = $node->getNext();
    $previous = $node->getPrevious();
    $previous->setNext($next);
    $next->setPrevious($previous);
}

这里的$node是函数内部的变量,它拿着和外部传入节点一样的对象标识符。你调用$previous->setNext($next)这类方法时,是通过标识符找到对应的对象,直接修改对象的属性——相当于拿着地址牌找到房子,然后改动房子里的结构。所以外部的链表自然会跟着变化,因为你操作的是同一个真实对象。

为什么countNode里的赋值不会影响外部的$node?

再看countNode函数的关键逻辑:

function countNode(Node $node) {
    $i = 0;
    while (null !== $node) {
        $i++;
        $node = $node->getNext(); // 重点在这一行
    }
    return $i;
}

这里的$node = $node->getNext(),是给函数内部的$node变量重新赋值——相当于把手里的地址牌换成了下一个房子的地址牌。但外部的那个$node变量,手里还是拿着原来头节点的地址牌,完全不受内部变量的影响。

举个生活化的例子:你和朋友各拿着一张写着"XX小区1号楼"的纸条(对象标识符)。朋友拿着纸条去小区,把1号楼和2号楼之间的门拆了(对应remove里修改对象属性),你再去看的时候,门确实没了;但如果朋友把自己手里的纸条换成"XX小区2号楼"(对应countNode里重新赋值变量),你手里的纸条还是写着1号楼,你去看的还是1号楼,不会变成2号楼。

所以第一次调用countNode($node)时,内部遍历完后,内部的$node变成null,但外部的$node依然指向原来的头节点;remove操作移除一个节点后,第二次调用countNode($node)自然会返回4。

内容的提问来源于stack exchange,提问作者Doğan Uçar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 07:52:34