通过引用传递的数组的奇怪行为

Strange behavior for arrays passed by reference

我刚刚得到一个简单函数的意外结果,该函数的参数通过引用传递。

假设我们有以下数组:

$arr = array(
  'Test' => 1,
  'OtherKey' => 2,
);
$keyTranslation = array(
  'OtherKey' => 'other_key',
  'Test' => 'test',
);

$keyTranslation 数组的键定义顺序可能与 $arr 不同。这只是为了说明功能的需要。

和以下函数:

function test(&$arr, $keyTranslation) {
    foreach ($arr as $key => $value) {
        $arr[$keyTranslation[$key]] = $value;

        unset($arr[$key]);
    }
}

意外的结果是简单地调用以上述数组作为参数的函数:

test($arr, $keyTranslation);

我在期待什么?

array(2) {
  ["test"]=>
  int(1)
  ["other_key"]=>
  int(2)
}

我得到了什么?

NOTICE Undefined index: test on line number 10

NOTICE Undefined index: other_key on line number 10

NOTICE Undefined index: on line number 10
array(0) { }

为什么会这样?

因为每次我向传递的引用数组添加一个新值时,循环也会遍历该值并将其取消设置。

问题

这正常吗?还是 PHP?

中的错误

这里没有错误。首先 $arr 中的键是 'Test''OtherKey'。在您的函数中,您尝试访问不存在的 $arr['test']$arr['other_key'],因此会出现通知。然后您取消设置密钥,因此结果是 $arr 在函数调用后为 null,因为您通过引用传递了 $arr

这就是我要使用的方法,因为在 foreach 遍历它时设置和取消设置数组的元素似乎有点狡猾...

function test(&$arr, $keyTranslation) {

    $newarr = array();

    foreach ($arr as $key => $value) {
        $newarr[$keyTranslation[$key]] = $value;
    }

    $arr = $newarr; // Not sure if you'd have to unset $arr first...
}

确保测试翻译后的密钥是否存在:

<?php

$arr = [ 'Foo' => 1, 'Bar' => 2 , 'dont_change' => 3, ];
$trans = [ 'Foo' => 'bar', 'Bar' => 'foo', 'Foobar' => 'foobar', ];


function test(&$arr, $trans) {
   foreach($arr as $key => $value) {
       if (!isset($trans[$key])) continue;
       $arr[$trans[$key]] = $value;
       unset($arr[$key]);
   }
}

test($arr, $trans);
print_r($arr);