PHP函数数组参数的引用
为什么这个代码不能像我预期的那样工作? 在Test(&$array)函数中,我将ref参数设置为全局$array1,但这不起作用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
$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.
指的是一个特定的值——PHP内部某处的一个存储桶,可以存储数字、字符串等$foo
- 每次使用普通赋值运算符时,例如,
,PHP都会查找所指向的值并对其进行更新-因此标识符$foo=42
没有更改,但它指向的值已更改$foo
- 当您分配引用时,例如,
,实际上是在告诉PHP更改标识符本身。所以现在,$bar=&$foo
和$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
唯一棘手的情况是对象,正如在许多语言中一样,对象本身都有一个额外的间接层次,而
$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&