php 使用三元运算符和按引用取值的foreach中出现意外行为

6rqinv9w  于 2022-12-17  发布在  PHP
关注(0)|答案(2)|浏览(154)

bounty将在5天后过期。回答此问题可获得+50声望奖励。pmiguelpinto希望引起更多人关注此问题。

为什么下面的代码在PHP 5.5.* 和PHP 7.* 中有不同的输出:

<?php
$foo = ['bar'=>[['item1'=>'value1']]];
foreach ($foo['bar'] ?: [] as $k => &$arr1) {
  $arr1['item1'] = 'value2';
}

var_dump($foo);

在PHP 5中,$foo['bar'][0]['item1']的值将被修改为value2,但在PHP 7中不会。

64jmpszr

64jmpszr1#

请尝试运行此代码.它完全工作在PHP8

$foo = ['bar'=>[['item1'=>'value1']]];
foreach ($foo['bar'] ?: [] as $k => &$arr1) {
  $foo['bar'][$k]['item1'] = 'value2';
}

var_dump($foo);
5cnsuln7

5cnsuln72#

documentation(强调我的):* 请注意,三元运算符是一个表达式,它的计算结果不是变量,而是表达式的结果。**如果要通过引用返回变量,了解这一点非常重要。*语句return $var == 42?$a:$B;在一个引用返回函数中将不起作用,并发出警告。
在PHP 5中,注意最里面的&array(1)是如何引用的:

array(1) {
  ["bar"]=>
  array(1) {
    [0]=>
    &array(1) {
      ["item1"]=>
      string(6) "value2"
    }
  }
}

但在PHP 7中,情况并非如此:

array(1) {
  ["bar"]=>
  array(1) {
    [0]=>
    array(1) {
      ["item1"]=>
      string(6) "value1"
    }
  }
}

如果删除?: [],那么循环的表达式就是$foo['bar'],那么代码在PHP 5和PHP 7中的行为是相同的,即最里面的&array(1)是一个引用。

TLDR:我不能说 * 为什么 * 会这样,也不能解释其中的区别,但很明显PHP 7处理条件运算符?:的方式与PHP 5不同。

相关问题