3

为什么这段代码不能像我预期的那样工作?在 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呢?它在函数内部之前“链接”!

4

2 回答 2

5

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

它曾经有对 的引用$array2,但现在它包含对 的引用$array1。因此,当您修改 时$array,您正在修改$array1.

于 2013-01-14T20:33:26.100 回答
2

这是我对 PHP 中的引用的理解,以及为什么该代码没有达到您的预期(如果我弄错了,请有人跳到我身上,我经常使用引用!另外,我确信有比我更好的术语'm call "identifier" and "value";我只是想避免在这两个概念中使用“变量”。)

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

PHP 中普通值的引用系统始终只包含一层间接性——例如,您不能像在 C 中那样创建指向指向指针的指针的指针。

The only tricky case is objects, which as in many languages have an extra level of indirection all of their own - whereas $foo = 42; $bar = $foo; copies the data representing 42 from $foo's value to $bar's, $foo = new stdClass; $bar = $foo copies an object pointer. So although $foo and $bar still have separate values, and an assignment like $foo = 42 won't have any effect on $bar, $foo->a = 1; and $bar->a = 1 will both end up changing the same object.

于 2013-01-14T21:50:23.323 回答