【散分】看看错误使用“引用”的恶果,你能看出是为什么吗?

maquan 2011-10-19 02:18:42
工作中遇到一个 BUG,检查到最后发现是对“引用”的不小心使用导致的,结果是一个 array 的最后两个元素变成相同的了。为了突出主要问题,我把程序的简化形式写在下面。有兴趣的童鞋可以想一想为什么会导致那样的结果。
$list = array(1,2,3);
foreach ( $list as &$item ) {
$a = $item;
}
//unset($item); // 正确的用法,应该是加上这句。
foreach ( $list as $item ) {
$a = $item;
}
var_dump($list); // 输出的是 { 1, 2, 2 ],有趣吧?



————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
...全文
225 15 打赏 收藏 转发到动态 举报
写回复
用AI写文章
15 条回复
切换为时间正序
请发表友善的回复…
发表回复
liuahuilele 2011-10-19
  • 打赏
  • 举报
回复
路 过
夏之冰雪 2011-10-19
  • 打赏
  • 举报
回复
使用引用,然后当不用的时候,或重新用的时候最好把之前的清空,然后再用,可以这样理解么?
黄袍披身 2011-10-19
  • 打赏
  • 举报
回复
谢谢提醒,回头赶紧看看代码,貌似我也有这种错误存在。卡卡
tottyandbaty 2011-10-19
  • 打赏
  • 举报
回复
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
跳动de指尖 2011-10-19
  • 打赏
  • 举报
回复
观看完毕
tottyandbaty 2011-10-19
  • 打赏
  • 举报
回复
有点意思。
maquan 2011-10-19
  • 打赏
  • 举报
回复
hehe,看来还真是个老问题,手册里都说过的。汗~~

其实我也早就知道引用不解除的话会有隐患,只是一开始想当然地以为即使出问题也应该是第一个元素,加之实际代码是分散在两处,就没往“引用”上想。

“末两个元素变成相同”这个现象一开始看觉得非常诡异,楼上各位分析得都对,把过程分解下来看清楚,就很简单了。

好了,这个帖子再挂一天就结了 :)


————————————————————————————————
基于CSDN论坛提供的插件扩展功能,自己做了个签名档工具,分享给大家,欢迎技术交流 :)
ci1699 2011-10-19
  • 打赏
  • 举报
回复
再来一个。



<?php
$list = array(1,2,3,4);
foreach ( $list as &$item ) {
}

// 这时$item指向$list[3]
foreach ( $list as $item ) {
// 第一次 这时$list[0] = 1。 所以$list[3]=1 $list = array(1,2,3,1);
// 第二次 这时$list[1] = 2。 所以$list[3]=2 $list = array(1,2,3,2);
// 第三次 这时$list[2] = 3。 所以$list[3]=3 $list = array(1,2,3,3);
// 第三次 这时$list[3] = 3。 所以$list[3]=3 $list = array(1,2,3,3);
}
print_r($list); // 1,2,3,3

For_Ning 2011-10-19
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 foolbirdflyfirst 的回复:]

呵呵,这个是老问题啊,几年前就有坛友贴出来过。

PHP code
$list = array(1,2,3);
$item = & $list[2];//第一次foreach就是这个意思,$item引用数组最后一个元素;
//unset($item); // 正确的用法,应该是加上这句。
foreach ( $list as $item ) {//第一次$item被赋予1,则$li……
[/Quote]

解释很好



[Quote=引用 5 楼 zt_king 的回复:]

Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
一查发现手册上好大一个红框,
配合2L解释.
[/Quote]
我翻开看了 果然
ci1699 2011-10-19
  • 打赏
  • 举报
回复


<?php
$list = array(1,2,3);
foreach ( $list as &$item ) {
}

// 这时$item指向$list[2]
foreach ( $list as $item ) {
// 第一次 这时$list[0] = 1。 所以$list[2]=1 $list = array(1,2,1);
// 第二次 这时$list[1] = 2。 所以$list[2]=2 $list = array(1,2,2);
// 第三次 这时$list[2] = 2。 所以$list[2]=2 $list = array(1,2,2);
}
print_r($list); // 1,2,2




这么理解。正确吗?
ZT_King 2011-10-19
  • 打赏
  • 举报
回复
Reference of a $value and the last array element remain even after the foreach loop. It is recommended to destroy it by unset().
一查发现手册上好大一个红框,
配合2L解释.
ohmygirl 2011-10-19
  • 打赏
  • 举报
回复
foolbird牛啊,一眼就看出问题所在了。
赞个。。
决定仔细看一下程序。
ZT_King 2011-10-19
  • 打赏
  • 举报
回复
每天回帖即可获得10分可用分!小技巧:教您如何更快获得可用分
foolbirdflyfirst 2011-10-19
  • 打赏
  • 举报
回复
呵呵,这个是老问题啊,几年前就有坛友贴出来过。

$list = array(1,2,3);
$item = & $list[2];//第一次foreach就是这个意思,$item引用数组最后一个元素;
//unset($item); // 正确的用法,应该是加上这句。
foreach ( $list as $item ) {//第一次$item被赋予1,则$list[2]相应的值也变成了1,以此类推..
break;
//$a = $item;
}

//var_dump($list); // 输出的是 { 1, 2, 2 ],有趣吧?
var_dump($list);//因为前面的break,这回变成[1,2,1]了。
yunprince 2011-10-19
  • 打赏
  • 举报
回复
很少用引用的路过

21,880

社区成员

发帖
与我相关
我的任务
社区描述
从PHP安装配置,PHP入门,PHP基础到PHP应用
社区管理员
  • 基础编程社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧