背景
同事写的代码,上传数据的时候,总是会最后一条数据被上一条数据覆盖掉,导致倒数第二条数据出现两次,最后一条数据丢失
发现问题
经排查,是对同一数据进行多次foreach时,有时用的引用传参,有时没有用引用传参造成的,复现问题如下:
$test_array = array(
'one' => '小明',
'two' => '小张',
'three' => '小刚',
);
foreach ($test_array as &$item) {
}
foreach ($test_array as $item) {
}
var_dump($test_array);die;
上述代码,循环中并没有对数组进行任何操作,输出结果为
与预期结果严重不符
原理分析
出现这个问题的原因的引用传参的使用,引用传参的使用方法是,使当前的变量只是对原变量的地址的引用,而不是内容的引用。
所以当第一个foreach使用引用传参时,循环结束时,value这个参数的数据路径和数组中的最后一个参数路径是一样的,这时无论对value进行什么样的操作,都会浮现到数组的最后一个参数上,所以当第二次遍历时,value被循环赋值,导致数组的最后一个参数也被不停赋值,这里最后一个参数会保留之上的最后一个参数
解决方案
- 引用传参变量不使用后对变量进行销毁
- 以后每次遍历都使用引用传参(不安全)
- 尽量不要在遍历中使用引用传参,改用$data[$key]的形式进行修改