PHP通过引用传递

时间:2012-04-17 00:05:51

标签: php

让我们假设以下内容:

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?

谢谢

请注意,此示例极为简化。

2 个答案:

答案 0 :(得分:5)

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

采用以下示例:

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

此时,Zend引擎表示您的字符串变量,其内容为Hello。

现在,如果你这样做:

$varCopy = $var;

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

简而言之,PHP非常聪明,在没有必要复制时,不会复制变量或数组的值。

您可以在PHP手册的Reference Counting Basics页面上了解详情。他们甚至在最后给出了一个特定阵列的例子。

一个有用的函数是memory_get_usage,它可以显示PHP正在使用多少内存。您可以使用它来跟踪当您传递阵列的多个副本时内存使用量将变化很小的事实。这有助于证明手册的参考计数基础部分中概述的要点。

您无需了解有关其工作原理的所有详细信息,但请注意PHP在创建和管理引用方面非常明智。

编辑:

直接回答你的实际问题,不,在func3 PHP中,即使你没有通过引用传递它,也不会复制数组。它将使用引用计数基础部分中所示的引用,因此您可以毫无顾虑地按值传递它。

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

答案 1 :(得分:1)

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

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

但是也要回答你的问题:

  

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

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