php问题,使用foreach循环数组两次并通过引用传递值

lon*_*ing 10 php arrays iteration foreach reference

我需要遍历一个数组两次 - 一次修改它的值,一次在html中显示它的内容.不幸的是,我遇到了麻烦.我已经创建了一个测试场景来说明问题.

$cases = array(
  array('caseStyle' => 'case style 1', 'caseNum' => 'case01'),
  array('caseStyle' => 'case style 2', 'caseNum' => 'case02'),
  array('caseStyle' => 'case style 3', 'caseNum' => 'case03'),
  array('caseStyle' => 'case style 4', 'caseNum' => 'case04'),
  array('caseStyle' => 'case style 5', 'caseNum' => 'case05'),
  array('caseStyle' => 'case style 6', 'caseNum' => 'case06')
);

foreach ($cases as $k => &$v) {
    $v['caseNum'] = ucwords($v['caseNum']);
}

foreach ($cases as $k => $v) {
    echo $v['caseNum'] . ' - ' . $v['caseStyle'] . '<br/>';
}
Run Code Online (Sandbox Code Playgroud)

这输出:

Case01 - case style 1
Case02 - case style 2
Case03 - case style 3
Case04 - case style 4
Case05 - case style 5
Case05 - case style 5
Run Code Online (Sandbox Code Playgroud)

请注意,最后一项的值是错误的.

如果在第二次迭代期间我使用 foreach($cases as $k => $d)而不是foreach($cases as $k => $v)或者如果我$v在第二次迭代之前取消设置,(unset($v))一切都会好起来的.这很有趣.我错过了什么?

DiM*_*ono 18

执行foreach循环时,()循环完成后持久化中的变量.这意味着在第一个循环结束后,您可以var_dump($v)在第一个循环的最后一次迭代之后获取其中包含的值.无论是引用(&$v)还是普通变量($v),都是这种情况.

但是,如果它是第一个循环中的引用,它仍然是引用,除非它未设置.这意味着当您进入第二个循环时,您将使用您当前正在查看的数组元素的值覆盖该引用.

请记住,foreach($cases as $k => $v)真正意味着"在$ cases中获取此元素的键并将其分配给$ k,并获取此元素的值并将其分配给$ v)".由于$ v仍然是对数组中最后一个元素的引用,而不是设置新变量$ v的值,实际上你正在更新$ v已经指向的值.

这意味着,如果我们简单地简化$ case,那么['a', 'b', 'c', 'd']在第一次通过第二次foreach之后,$ cases现在['a', 'b', 'c', 'a']是因为你已经在$ case中重新分配$ v指向的元素 - 最后一个 - 来拥有与第一个相同的价值.第二次,它是['a', 'b', 'c', 'b'].第三次通过它['a', 'b', 'c', 'c'].然后,最后一次,你将它分配给自己,并在那时它保持价值'c'.

这实际上只是php按预期工作的情况.解决方案是unset($v)在第一个循环结束后,确保下次使用$ v时,您使用的是新变量,而不是现有的引用.

要看到这个:

转到http://phpfiddle.org/并粘贴以下代码,然后运行它; 您将$v在第一个循环完成后保留的输出中看到,并且$cases[5]每次通过第二个循环更改的值.

$cases = array(
  array('caseStyle' => 'case style 1', 'caseNum' => 'case01'),
  array('caseStyle' => 'case style 2', 'caseNum' => 'case02'),
  array('caseStyle' => 'case style 3', 'caseNum' => 'case03'),
  array('caseStyle' => 'case style 4', 'caseNum' => 'case04'),
  array('caseStyle' => 'case style 5', 'caseNum' => 'case05'),
  array('caseStyle' => 'case style 6', 'caseNum' => 'case06')
);

foreach ($cases as $k => &$v) {
    $v['caseNum'] = ucwords($v['caseNum']);
}
var_dump($v);
echo "<br />";
foreach ($cases as $k => $v) {
    print_r($cases);
    echo "<br />";
    echo $k . ': ' . $v['caseNum'] . ' - ' . $v['caseStyle'] . '<br/>';
}
Run Code Online (Sandbox Code Playgroud)


und*_*one 2

尝试这个:

foreach ($cases as $k => &$v) {
    $cases[$k]['caseNum'] = ucwords($v['caseNum']);
    echo $cases[$k]['caseNum'] . ' - ' . $cases[$k]['caseStyle'] . '<br/>';
}
Run Code Online (Sandbox Code Playgroud)