2

让我们假设以下内容:

private $array = array(/*really big multi-dimensional array*/);

public function &func1($specific_large_sub_array_key)
{
     return $this->array[$specific_large_sub_array_key]
}

public function func2()
{
    $specificArray = &$this->func1(1);

    $this->func3($specificArray);
}


public function func3($specificArray)
{
    /* do stuff here*/
}

我的问题是这样的:

如果 func3 没有指定 $specificArray 不是通过引用传递给它的,那么 PHP 在 func2 内部调用 func3 时会复制 $specificArray 吗?还是 PHP 会保留引用并自动传播它?

即这会...

public function func3($specificArray)
{
    unset($specificArray[234]);
}

...影响$array?

谢谢

请注意,此示例非常简化。

4

2 回答 2

5

PHP 在如何处理变量和副本方面非常聪明。

举个例子:

// Allocate one variable with content 'Hello'
$var     = 'Hello';

此时,Zend 引擎有一个字符串变量的表示形式,内容为 Hello。

现在,如果你这样做:

$varCopy = $var;

您有 2 个自变量 ($var$varCopy),但由于它们的内容相同,因此内容仅存在于内存中的一个位置(基本上尚未制作真正的副本)。此时,两个变量在符号表中引用相同的值(Hello)。一旦修改了两个变量之一,它只会复制内容。同样的逻辑适用于 2 个副本到任意数量的副本。

简而言之,PHP 足够聪明,不会在不需要复制时复制变量或数组的值。

您可以在 PHP 手册的参考计数基础页面上了解更多信息。他们甚至在最后给出了一个特定于数组的示例。

一个有用的函数是memory_get_usage,它可以显示 PHP 正在使用多少内存。您可以使用它来跟踪这样一个事实,即当您传递数组的多个副本时,内存使用量几乎不会发生变化。这可以帮助证明手册的引用计数基础部分中概述的要点。

您不需要了解有关其工作原理的所有细节,但请注意 PHP 在创建和管理引用方面非常聪明。

编辑:

要直接回答您的实际问题,不,func3即使您不通过引用传递它,PHP 也不会复制数组。它将使用引用计数基础部分中说明的引用,因此您可以按值传递它而无需担心。

但是,如果您调用 unset,则您取消设置的值只会从数组的本地副本中删除,因此它最终不会从源数组中删除,除非您通过对函数的引用传递它。但是按值传递它并不会创建整个巨大数组的全新副本。即使从副本中删除一个值也不会创建一个全新的副本减去您删除的条目(您只有第二个数组,其中所有引用都与第一个相同,但它缺少对已删除条目的一个引用)。

于 2012-04-17T00:16:26.323 回答
1

不能做多行注释,所以作为答案:

return &$this->array[$specific_large_sub_array_key]
       ^

但也要给你一个问题的答案:

即这... [...] ...影响$array吗?

简单明了:不。原因:这是一个不同的变量,而不是别名(参考)。

于 2012-04-17T00:15:17.330 回答