PHP函数数组参数的引用

PHP函数数组参数的引用,php,arrays,function,reference,Php,Arrays,Function,Reference,为什么这个代码不能像我预期的那样工作? 在Test(&$array)函数中,我将ref参数设置为全局$array1,但这不起作用 $array1 = array(); $array2 = array(); function Test(&$array) { global $array1; $array = &$array1; $array['inside'] = 'inside'; } //由函数设置: Test($array2); $arr

为什么这个代码不能像我预期的那样工作? 在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 **
//在不使用该功能的情况下设置:

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'值outside。如果我设置$array2['test1']='test1'为什么不同时更改$array1呢?它的'链接'前内的功能

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


它以前有一个对
$array2
的引用,但现在它包含了对
$array1
的引用。因此,当你修改
$array
时,你就是在修改
$array1
以下是我对PHP中引用的理解,以及为什么这些代码没有达到你期望的效果(如果我弄错了,请有人跳到我身上,我经常使用引用!而且,我相信还有比我称之为“标识符”和“值”更好的术语);我只是想避免对这两个概念使用“变量”。)

  • 有一组变量标识符(获取数据的方式)和一组变量值(数据实际所在的位置)
  • 对于正态变量,只有一个标识符指向一个值。e、 g.
    $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
    仍然指向的旧值没有更改
  • 还有其他类似的情况。例如,
    global
    static
    关键字创建指向现有值的额外标识符。如果编写
    函数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
最终都会改变同一个对象。

听说过返回值吗?@kingcrunch这显然是一个简化的测试用例,所以批评未知的用例似乎毫无帮助。@IMSoP OK,抱歉:)但老实说:我已经多年没有看到一个有用的in-out参数用例了,我担心它们已经不存在了。但是我看到了微优化的pass-by-reference(除此之外:它没有优化任何东西,因为写时复制),然后同样的开发人员感到困惑,因为数组“神奇地”改变了,因为其他一些人使用数组,比如一个使用数组,作为参数传递:)我想说的是:没有真正的用例,但有很多“wtf”-MOMEMT正在等待。@KingCrunch:实函数在通过引用设置多个参数值时应返回布尔值。这是我的.NETC#解决方案中的一种设计模式。我只是想用php实现它。@ggabor这种“返回值作为状态参数”是个坏习惯。当你的方法失败时,使用异常,当它成功时。。好吧,不要抛出异常;)然后继续。这就是异常存在的原因:通知您(并给您机会对异常情况做出反应)。平心而论:也许在其他语言中这是一种更为普遍的模式,但至少在我所知道的语言中不是这样:)(我对C族不太熟悉)它总是让我绞尽脑汁,弄清楚
=&
到底能做什么,因为您必须区分作为标签的变量和作为某个值的容器的变量。@IMSoP:the
&