首页 > 解决方案 > PHP 对象引用

问题描述

我对 PHP 如何处理对象和引用感到困惑。我知道在分配给变量或传递给函数时,对象是通过引用分配或传递的。但是,以下示例令人困惑:

$node = new Node("a", 1);
$a = new Node("b", 2);
$b = new Node("c", 3);
$c = new Node("d", 4);
$d = new Node("e", 5);
$d->setPrevious($c);
$d->setNext(null);

$c->setNext($d);
$c->setPrevious($b);

$b->setNext($c);
$b->setPrevious($a);

$a->setNext($b);
$a->setPrevious($node);

$node->setNext($a);
$node->setPrevious(null);

echo countNode($node);
echo "\n";
remove($node->getNext());
echo countNode($node);
echo "\n";

function countNode(Node $node) {
    $i = 0;
    while (null !== $node) {
        $i++;
        $node = $node->getNext();
    }
    return $i;
}

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

    $previous->setNext($next);
    $next->setPrevious($previous);
}

其中输出如下:

5
4

我知道我不需要从“删除”方法返回节点对象,因为该对象是通过引用传递的。但是“countNode”方法是什么?$node变量必须是,null不是吗?

更新

由于这个问题似乎模棱两可,我想更准确地问这个问题:remove方法改变了$node. 从双向链表中删除一个节点后,大小从 5 减少到 4。

但是countNode也在重新分配$node变量,因此必须返回 0?!为什么参考没有改变countNode

标签: phpobjectreference

解决方案


$node不会为 NULL,因为在您的函数remove中您没有将 设置$node为 NULL。您应该通过以下方式更新您的remote功能

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

    $previous->setNext($next);
    $next->setPrevious($previous);
    $node = null;
}

的引用$node不会在内存中清理,它总是在 php应用程序关闭之前存在或您将其设置为NULL

更新

function countNode(Node $node) {
    $i = 0;
    while (null !== $node) {
        $i++;
        $node = $node->getNext(); //This Line
    }
    return $i;
}

您的代码countNode将列表的第一个节点更改为,因为您在执行 while 循环时NULL更新了变量。$node然后,当 while 循环结束时,此行将您的 $note 变量引用更新为 NULL。

阅读有关对象参考的更多信息:

https://www.toptal.com/php/objects-references-php-memory


推荐阅读