php中使用& 导致的一个bug 海诺博客 bug 来源

bug 来源

今日徒弟在对数据进行处理时 用了多个foreach,且在foreach的时候对value进行了引用,最后在循环处理时,发现之前的一个一维数组的最后一个元素变成了一个数组,这个bug可以精简为两个foreach。

bug 复现

具体代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
复制代码$a=[
1=>['a','b','c'],
2=>['v','d','r'],
3=>['v4','d4','r4'],
4=>['v5','d5','r5']
];
$b=[1=>55,2=>5,3=>677,4=>9];
foreach($b as &$value){
$value=intval($value);
if($value<1){
exit('数据有误!');
}
}
foreach($a as $key=>$value){
if($key==4){
var_dump($b[$key]);
}
}

这个时候你会发现输出是这样的

1
2
3
4
5
6
7
8
复制代码array(3) {
[0]=>
string(2) "v5"
[1]=>
string(2) "d5"
[2]=>
string(2) "r5"
}

变更下代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
复制代码$a=[
1=>['a','b','c'],
2=>['v','d','r'],
3=>['v4','d4','r4'],
4=>['v5','d5','r5']
];
$b=[1=>55,2=>5,3=>677,4=>9];
foreach($b as &$value){
$value=intval($value);
if($value<1){
exit('数据有误!');
}
}
var_dump($b);
foreach($a as $key=>$value){
if($key==4){
var_dump($b[$key]);
}
}

会看到这样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
复制代码array(4) {
[1]=>
int(55)
[2]=>
int(5)
[3]=>
int(677)
[4]=>
&int(9)
}
array(3) {
[0]=>
string(2) "v5"
[1]=>
string(2) "d5"
[2]=>
string(2) "r5"
}

bug 产生原因

在【4】=>&int(9) 这个int什么鬼啊。这里其实就是引用的原因

产生条件一

必须是key有关联,例如第一数组的key是第二个数组的索引,或者第一个数组的元素的某个key的值是B的索引key

产生条件二

必须是在循环第一个数组之前循环第二个数组,且循环第二数组时使用的是引用传值

产生条件三

必须是两个foreach使用的相同的as后的参数,例如本例 形参均为$value

产生条件四

在第二个froeach循环中使用了$value

bug解析

原因就是 这个引用 ,第一个循环 将$value设置为引用后,第二个循环的$value 自动使用了第一个循环最后一个$value的内存,第二个value变化,也会引起第一个循环的最后一个$value变化。

解决办法

在每一个使用引用方式的foreach后增加一个unset($value);

最终无bug代码

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
复制代码$a=[
1=>['a','b','c'],
2=>['v','d','r'],
3=>['v4','d4','r4'],
4=>['v5','d5','r5']
];
$b=[1=>55,2=>5,3=>677,4=>9];
foreach($b as &$value){
$value=intval($value);
if($value<1){
exit('数据有误!');
}
}
//循环结束后,将循环的形参干掉
unset($value);
foreach($a as $key=>$value){
if($key==4){
var_dump($b[$key]);
}
}

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%