Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/286.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 重新分配引用数组的变量会重新分配原始变量_Php - Fatal编程技术网

Php 重新分配引用数组的变量会重新分配原始变量

Php 重新分配引用数组的变量会重新分配原始变量,php,Php,我有以下代码: $originalBar=[ ‘baz’=>18 ]; 函数修改(&$bar){ $bar['test']=true; $bar=[ “数据”=>42 ]; 全球$originalBar; 回显“相同”。($bar===$originalBar); } 修改($originalBar); var_dump($originalBar); 我知道,由于函数通过引用接受参数,因此任何传递的数组都将被修改。因此,我希望通过以下方式更改原始阵列: $bar['test'] = true;

我有以下代码:

$originalBar=[
‘baz’=>18
];
函数修改(&$bar){
$bar['test']=true;
$bar=[
“数据”=>42
];
全球$originalBar;
回显“相同”。($bar===$originalBar);
}
修改($originalBar);
var_dump($originalBar);
我知道,由于函数通过引用接受参数,因此任何传递的数组都将被修改。因此,我希望通过以下方式更改原始阵列:

$bar['test'] = true;
…并将
$originalBar
test
键设置为
true
。但是,当我重新分配
$bar
时,我希望变量不再指向原始数组(
$originalBar
),并且以后的任何更改都不会修改它。显然,情况并非如此,因为输出是:

same 1
array(1) {
  ["data"]=>
  int(42)
}
通过重新分配
$bar
,我也重新分配了
$originalBar
。我希望它的功能与JavaScript中的功能相同,这就是我一开始感到困惑的原因

我的问题是——这是否有记录在案?我读了文档,但没有在那里找到

编辑:如果不在修改功能中执行此操作:

$bar=[
“数据”=>42
];
…我这样做:

$arr=[
“数据”=>42
];
$bar=&$arr;
…我得到了我最初预期的结果:

same 
array(2) {
  ["baz"]=>
  int(18)
  ["test"]=>
  bool(true)
}

有趣的是,在本例中,
$originalBar
未被分配给
$arr
的值,而是保留其旧值。

由于这是预期的行为,因此未在任何地方进行记录。我刚才误读了。PHP文档说:

您可以通过引用将变量传递给函数,以便该函数可以修改变量

我有一个错误的印象,因为在JavaScript中默认情况下对象是通过引用传递的,因此重新分配参数变量不会改变原始变量

在PHP中通过引用传递的目的是能够修改变量,而不仅仅是它指向的对象。也就是说,您不仅可以更改对象,还可以重新分配传递的变量

正如@ggorlen在对我的问题的评论中所说:

引用操作符实际上做了两件事:1)公开原始内存位置以进行重新分配;2)允许复杂结构(如数组)发生变异。在JS中,第一个永远不可能,第二个总是可能的。PHP在这些方面提供了一些“灵活性”,一方面,
function($var)
比大多数语言更严格,而
function(&$var)
比大多数语言更宽松,这并不完全是直观的


这在任何地方都没有记录,因为这是预期的行为。我刚才误读了。PHP文档说:

您可以通过引用将变量传递给函数,以便该函数可以修改变量

我有一个错误的印象,因为在JavaScript中默认情况下对象是通过引用传递的,因此重新分配参数变量不会改变原始变量

在PHP中通过引用传递的目的是能够修改变量,而不仅仅是它指向的对象。也就是说,您不仅可以更改对象,还可以重新分配传递的变量

正如@ggorlen在对我的问题的评论中所说:

引用操作符实际上做了两件事:1)公开原始内存位置以进行重新分配;2)允许复杂结构(如数组)发生变异。在JS中,第一个永远不可能,第二个总是可能的。PHP在这些方面提供了一些“灵活性”,一方面,
function($var)
比大多数语言更严格,而
function(&$var)
比大多数语言更宽松,这并不完全是直观的


我想纠正问题、评论和自我回答中的一些误解

  • 在PHP中传递对象的行为类似于在JS中传递对象。这不是通过引用传递,而是通过值传递“对象指针”;两者之间的区别是微妙但重要的。当通过引用将变量传递到函数中时,可以在函数内部为该变量指定任何值,并且该值也将位于函数外部。传递一个对象并没有给你这种能力-你不能用一个不同的对象,或者用值
    42
    替换它-但是它允许你改变对象-你可以调用一个方法或设置一个属性,函数外的代码将能够看到结果
  • JS和PHP之间的区别在于,JS中的数组是对象,而PHP中不是对象,因此当通过值传递时,它们没有这种“可变对象指针”行为
  • 在PHP和许多其他语言中实现的passbyreference意味着函数内部变量的任何赋值或修改都会反映在函数外部。这里的数组没有什么特别之处,同样的事情发生在
    $foo=42
    $foo++
  • JS没有一个等价的显式传递引用,但其他语言,如C#和Pascal,具有相同的概念和不同的语法
在PHP中,当您通过引用赋值(
$foo=&$bar
)时,事情会变得更不寻常;一种方法是,你有一个变量,你给它两个名字


我更喜欢将您编写的
$bar=&$newValue
拼写为
$bar=&$newValue
,因为该操作实际上不是“将某个对象分配给
$bar
”,而是“将名称
$bar
绑定为某个对象的别名”。在绑定该别名时,它会丢弃该名称以前的任何绑定,因此它会撤消该名称的“按引用传递”性质。

我想纠正问题、注释和自我回答中的一些误解<
function modify($a) {
    global $foo;
    var_dump($a === $foo); # => true

    $a['hello'] = "world";
    var_dump($a === $foo); # => false, we wrote to $a and it was copied.
}

$foo = ["baz" => 42];    
modify($foo);
var_dump($foo); # => ["baz" => 42] (the original was unchanged after the function call)