当前位置: 首页 > news >正文

php灵异事件,啥都没干数据变了?

这篇文章也可以在我的博客查看

搞WordPress,难免跟php打交道
然而这弱类型语言实在坑有点多
这不今儿又踩了个大坑直接时间-1😅

问题

话不多说直接上代码

<?php
$items = [1,2];foreach ($items as &$item) {/*empty loop*/}
print_r($items);foreach ($items as $item) {/*empty loop*/}
print_r($items);

请问,最后的输出是什么?
答案是:

Array
([0] => 1[1] => 2
)
Array
([0] => 1[1] => 1
)

不是,我啥也没干呢,发生什么事了?
我懂了,一定是我的/*empty loop*/注释把数据改了!(不是)

原因

原因其实有二,但凡php没那么“强大”都不会造成这个问题

  1. php支持“引用”,而非指针
  2. php的变量作用域由定义开始生效直到函数/文件结束,不存在代码块为基础的局部作用域(花括号)

同时满足这俩条件的语言好像还真蛮少的
因此我这不就暴毙了嘛

  1. 首先第一个循环,使用引用对$item赋值
  • 因此循环结束后,$item事实上是最后一个元素的引用
  1. 然后,循环结束后,$item没有因为循环结束而终止生命周期
  • 因此第二次循环的$item事实上还是指向最后一个元素的引用
  1. 最后,第二次循环没有使用引用赋值
  • 因此改变的不是引用指向,而是引用当前指向的值

因此,最后一个元素在第二次循环中被赋值了n次

小测试

如果$items=[1,2,3],最后的结果是什么?
答案是:Array([0] => 1 [1] => 2 [2] => 2)

这个错误造成的不是第二次输出全部重复,而只是第n个元素被修改成n-1的值
跟着循环走一遍就很好理解:

  1. 第一步$item = $items[0] === 1,此时$items[2] === $item === 1
  2. 第二步$item = $items[1] === 2,此时$items[2] === $item === 2
  3. 第三步$item = $items[2] === 2(因为上一步)

谢谢你,我的PHP😅

参考资料

PHP Foreach Pass by Reference: Last Element Duplicating? (Bug?)

http://www.lryc.cn/news/141007.html

相关文章:

  • 【ffmpeg】基于需要使用videocapture的opencv编译配置(C++)
  • Redisson分布式锁 原理源码 分析
  • Cocos独立游戏开发框架中的事件管理器
  • keepalived+haproxy 搭建高可用高负载高性能rabbitmq集群
  • 网络安全(黑客)零基础自学
  • 如何把本地项目上传github
  • 跳跃游戏【贪心算法】
  • vue2+element-ui 实现下拉框滚动加载
  • 探索AIGC人工智能(Midjourney篇)(二)
  • 01-Flask-简介及环境准备
  • 【Git游戏】远程分支
  • Day07-ElementUI
  • 【Go 基础篇】Go语言中的defer和recover:优雅处理错误
  • 4.15 TCP Keepalive 和 HTTP Keep-Alive 是一个东西吗?
  • 如何在VSCode中将html文件打开到浏览器
  • 2022年03月 C/C++(四级)真题解析#中国电子学会#全国青少年软件编程等级考试
  • 五公里场地训练笔记(完整版)
  • 【电能质量扰动】基于ML和DWT的电能质量扰动分类方法研究(Matlab实现)
  • 使用 OpenAI GPT 模型的最佳实践
  • 解除用户账户控制提醒
  • 行业追踪,2023-08-23
  • 算法修炼Day60|● 84.柱状图中最大的矩形
  • 前端面试题css(一)
  • .NETCORE中关于swagger的分组
  • 4.1011
  • uniapp中引入axios的错误?
  • Discuz!论坛发帖标题字数限制80字符可以修改吗?修改发帖标题字数的方法
  • R语言画样本不均衡组的箱线图
  • ArcGIS学习总结(19)——要素转点与空间连接(属性表字段映射)
  • 【每日一题Day306】LC228汇总区间 | 双指针