PHP函数数组参数引用


PHP function array parameter by reference

为什么这段代码不像我预期的那样工作?在Test(&$array)函数中,我将ref参数设置为全局$array1,但这不起作用。

$array1 = array();
$array2 = array();
function Test(&$array)
{
    global    $array1;
    $array = &$array1;
    $array['inside'] = 'inside';
}

//由函数设置:

Test($array2); 
$array2['test1'] = 'test1';
var_dump($array1); //array('inside' => 'inside') ** WHERE IS THE 'test1'  key? **
var_dump($array2); //array('test1' => 'test1')   ** WHERE IS THE 'inside' key? **

//设置没有函数:

$array2 = &$array1;
$array2['test2'] = 'test2';
var_dump($array1); //array('inside' => 'inside', 'test2' => 'test2') ** FINE **
var_dump($array2); //array('inside' => 'inside', 'test2' => 'test2') ** FINE **
编辑:

很明显,如果我改变$array指向$array1,那么$array1将有'inside' => 'inside'值函数之外。什么不清楚,如果我设置$array2['test1'] = 'test1' 为什么不改变这个$array1也?它在函数内部之前被"链接"了!

当您在函数中执行$array = &$array1;时,您正在更改局部变量$array的值。

它过去有一个对$array2的引用,但现在它包含一个对$array1的引用。所以当你修改$array时,你也在修改$array1

这是我对PHP中引用的理解,以及为什么代码不像你期望的那样(如果我弄错了,请有人跳出来,我经常做引用!此外,我相信有比我所说的"标识符"answers"价值"更好的术语;我只是想避免在任何一个概念中使用"变量"。

  • 有一堆变量标识符(获取数据的方式)和一堆变量值(数据实际所在的位置)
  • 对于普通变量,只有一个指向一个值的标识符。例如,$foo指的是一个特定的值——PHP内部某个地方的一个桶,可以容纳数字、字符串等。
  • 每次你使用正常的赋值操作符,例如$foo = 42, PHP寻找被指向的值并更新它-所以标识符$foo没有改变,但它指向的值已经改变了。
  • 当你指定一个引用时,例如$bar =& $foo,你实际上是在告诉PHP改变标识符本身。所以现在$bar$foo是指向相同值的两个不同的标识符。$foo = -1$bar = -2都将写入这个值,无论你给它取什么名字,你都是在引用这个值。
  • 到目前为止,一切顺利。但如果我现在写$foo =& $bob呢?由于我正在更改标识符,而不是$foo开始指向与$bob相同的值,但$bar保持在原来的位置。所以现在,更改$foo不会对$bar产生任何影响。
  • 当你通过引用传递一个参数给一个函数时,也会发生类似的事情。因此,在问题中的示例中,Test($array2)行仍然在称为$array的函数中创建一个新的标识符,但它将其指向与$array2相同的。然而,在函数内部是$array = &$array1行,它接受新的标识符($array)并将其指向与$array1相同的值。旧的值,$array2仍然指向,没有改变。
  • 还有其他类似的情况。例如,globalstatic关键字创建了一个指向现有值的额外标识符。如果你写function foo() { global $foo; $bar = 2; $foo =& $bar; },只有函数的本地标识符$foo被更新为指向$bar的值;全局标识符(当你处于全局作用域时,它恰好也被称为$foo)仍然指向它的原始值。

PHP中普通值的引用系统总是包含仅一层间接 -例如,您不能像在C中那样创建指针指向指针的指针。

唯一棘手的情况是对象,在许多语言中都有额外的间接层——$foo = 42; $bar = $foo;将表示42的数据从$foo的值复制到$bar的值,$foo = new stdClass; $bar = $foo复制一个对象指针。因此,尽管$foo$bar仍然有单独的,并且像$foo = 42这样的赋值不会对$bar产生任何影响,但$foo->a = 1;$bar->a = 1最终都会改变相同的对象。