在PHP 7中,我使用这种构造来通过引用
处理一些数组值foreach ($this->values['key'] ?? [] as &$sub_value) {
$sub_value['sub_key'] = 'new value';
}
我用" ?? []"如果key不存在或为null则不显示错误。 问题是" ?? []"添加PHP不会对目标值进行任何更改,仅在局部变量中(必须是链接,但在这种情况下表现得像我没有指定"&"):
class DefaultSandbox extends PHPUnit_Framework_TestCase
{
private $values = array (
'key' =>
array (
1 =>
array (
'external_link' => '',
'description' => 'ku1231',
),
2 =>
array (
'is_external' => '1',
'external_link' => 'http://some.ru',
'description' => 'LAME',
),
),
);
public function testDefault()
{
foreach ($this->values['key'] ?? [] as &$sub_value) {
$sub_value['sub_key'] = 'new value';
}
print_r($this->values['key']);
}
}
阵列( [1] =>排列 ( [external_link] => [描述] => ku1231 )
[2] => Array ( [is_external] => 1 [external_link] => http://some.ru [description] => LAME )
)
为什么会这样?代码没有" ?? []"工作正常:
foreach ($this->values['key'] ?? [] as &$sub_value) {
$sub_value['sub_key'] = 'new value';
}
print_r($this->values['key']);
阵列( [1] =>排列 ( [external_link] => [描述] => ku1231 [sub_key] =>新的价值 )
[2] => Array ( [is_external] => 1 [external_link] => http://some.ru [description] => LAME [sub_key] => new value )
答案 0 :(得分:2)
它将左侧作为表达式的一部分,所以基本上它是一个数组的副本。您仍然可以修改该元素,但只是在该副本中。
如果键值为null,解决方法是在循环之前分配空数组。
答案 1 :(得分:2)
正在发生的事情是由于??
的工作方式,而数组是值,而不是对象。
??
相当于说:
(isset($arr) ? $arr : [])
或者,更长篇(但并不完全准确,但对于这个例子足够接近):
if(isset($arr) {
$__temp = $arr;
} else {
$__temp = [];
}
因为数组是值,所以?:
运算符(和扩展名为??
)会返回一个新值;不是原始变量。
当您遍历结果时,您将迭代该临时值,而不是原始数组。
在您的情况下,您需要执行以下操作:
if(!isset($arr)) {
$arr = [];
}
开始循环迭代之前;然后你会得到你期望的结果。
<小时/> 顺便说一下,如果你遍历一个对象,你将得到你想要获得的结果:
$obj = (object)[1, 2, 3];
foreach($obj ?? [] as &$val) {
$val++;
}
最后,$obj
将包含2,3和4.这是因为对象的“值”实际上是对象本身的引用,因此($obj ?? [])
return(基本上)是原始对象。