昨天写了一个很简单的接口,结果却因为遇上这么一个问题,调试了好久,简直要被自己整郁闷了。
郁闷就郁闷在一步步注释掉了代码,到最后简单到foreach里面只打印foreach外面的数组,结果却告诉我,foreach内外同一变量的值居然不一样,感觉脑子不够用了,实在想不通居然还会这样。
为了吸取经验,今天起早另写了一套简单的来复现了一下。
<?php $stu_info = array( array('stu_no'=>'20190810111', 'name'=>'zhaicoder' ), array('stu_no'=>'20190810112', 'name'=>'laowang' ), array('stu_no'=>'20190810113', 'name'=>'zhangsan' ), array('stu_no'=>'20190810114', 'name'=>'xiaohei' ), ); $stu_info_no_key = array_column($stu_info, null, 'stu_no'); foreach($stu_info_no_key as &$item){ $item['score'] = 0; //总分数 $item['sort'] = 0; //分数排名 } $stu_score = array( array('stu_no'=>'20190810111', 'score'=>89), array('stu_no'=>'20190810111', 'score'=>96), // array('stu_no'=>'20190810111', 'score'=>82), // array('stu_no'=>'20190810112', 'score'=>80), // array('stu_no'=>'20190810112', 'score'=>77), // array('stu_no'=>'20190810112', 'score'=>90), // array('stu_no'=>'20190810113', 'score'=>99), // array('stu_no'=>'20190810114', 'score'=>90), // array('stu_no'=>'20190810114', 'score'=>97), // array('stu_no'=>'20190810114', 'score'=>94), ); var_dump($stu_info_no_key); foreach($stu_score as $item){ var_dump($stu_info_no_key); }
问题就是上面代码结尾处foreach内外的同样一个数组,打印出来的内容却不一样。
$stu_info_no_key的前三条数据都正常,就是最后一条不正常:数据像被狗啃了一样,name和sort不见了。
array(4) { ["20190810111"]=> array(4) { ["stu_no"]=> string(11) "20190810111" ["name"]=> string(9) "zhaicoder" ["score"]=> int(0) ["sort"]=> int(0) } ["20190810112"]=> array(4) { ["stu_no"]=> string(11) "20190810112" ["name"]=> string(7) "laowang" ["score"]=> int(0) ["sort"]=> int(0) } ["20190810113"]=> array(4) { ["stu_no"]=> string(11) "20190810113" ["name"]=> string(8) "zhangsan" ["score"]=> int(0) ["sort"]=> int(0) } ["20190810114"]=> &array(2) { ["stu_no"]=> string(11) "20190810111" ["score"]=> int(89) } }
但是如果我把我中间的初始化工作换一种方式书写(如下所示),结果又是正常的。
foreach($stu_info as &$item){ $item['score'] = 0; //总分数 $item['sort'] = 0; //分数排名 } $stu_info_no_key = array_column($stu_info, null, 'stu_no');
如果你有兴趣找问题原因,那你就止步于此,去试一试吧。
原因出在我写的两个foreach里面都是用的$item变量来遍历的,至于$stu_info_no_key数组的最后一条数据为何被啃了,其实不是被啃了,只是被$stu_score的数据给替换了,正好$stu_score数组的数据key值在$stu_info_no_key的数据里都有,才会造成这样一种错觉。
额,至于为何$stu_info_no_key最后一条数据被替换掉了,隐隐约约感觉跟我用的引用有关,但我仍没想明白程序是怎么一步一步的给我挖了这么个隐藏的大坑。
2019年11月16日 晚更新:
由于第一个foreach遍历完,$item引用就指向了$stu_info_no_key的最后一条数据。
在第二个foreach遍历时,就相当于把$stu_score的每条数据依次赋值给$item,这样就相当于直接修改了$item之前的内容值,也就是$stu_info_no_key的最后一条数据的值了。
遍历foreach的内部变量尽量不用相同的变量名称