php灵异事件,啥都没干数据变了?
短信预约 -IT技能 免费直播动态提醒
这篇文章也可以在我的博客查看
搞WordPress,难免跟php打交道
然而这弱类型语言实在坑有点多
这不今儿又踩了个大坑直接时间-1😅
问题
话不多说直接上代码
$items = [1,2];foreach ($items as &$item) {}print_r($items);foreach ($items as $item) {}print_r($items);
请问,最后的输出是什么?
答案是:
Array( [0] => 1 [1] => 2)Array( [0] => 1 [1] => 1)
不是,我啥也没干呢,发生什么事了?
我懂了,一定是我的注释把数据改了!(不是)
原因
原因其实有二,但凡php没那么“强大”都不会造成这个问题
- php支持“引用”,而非指针
- php的变量作用域由定义开始生效直到函数/文件结束,不存在代码块为基础的局部作用域(花括号)
同时满足这俩条件的语言好像还真蛮少的
因此我这不就暴毙了嘛
- 首先第一个循环,使用引用对
$item
赋值
- 因此循环结束后,
$item
事实上是最后一个元素的引用
- 然后,循环结束后,
$item
并没有因为循环结束而终止生命周期
- 因此第二次循环的$item事实上还是指向最后一个元素的引用
- 最后,第二次循环没有使用引用赋值
- 因此改变的不是引用指向,而是引用当前指向的值
因此,最后一个元素在第二次循环中被赋值了n次
小测试
如果$items=[1,2,3]
,最后的结果是什么?
答案是:Array([0] => 1 [1] => 2 [2] => 2)
这个错误造成的不是第二次输出全部重复,而只是第n
个元素被修改成n-1
的值
跟着循环走一遍就很好理解:
- 第一步
$item = $items[0] === 1
,此时$items[2] === $item === 1
- 第二步
$item = $items[1] === 2
,此时$items[2] === $item === 2
- 第三步
$item = $items[2] === 2
(因为上一步)
谢谢你,我的PHP😅
参考资料
PHP Foreach Pass by Reference: Last Element Duplicating? (Bug?)
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341