PHP数组Key强制类型转换实现原理解析


Posted in PHP onSeptember 01, 2020

PHP是弱类型语言,就像JavaScript一样,在定义变量时,不需要强制指定变量的类型。同时,PHP又有着强大的数组功能,数组的Key即可以是普通的数字类型下标,也可以是字符串类型的Hash键值,那么,当一个数组的Key同时拥有字符串和数字时,会产生什么情况呢?

首先来看下面这样一段代码:

$arr = [
  "1" => "a",
  "01" => "b",
  1 => "aa",
  1.1 => "aaa",
  "0.1" => "bb",
];

var_dump($arr);

// array(3) {
//   [1] =>
//   string(3) "aaa"
//   '01' =>
//   string(1) "b"
//   '0.1' =>
//   string(2) "bb"
// }

咦?我们定义的"1"、1下标的值都变成了1.1的"aaa"了?

没错,PHP中的数组Key值只接受数字和字符串类型,当Key是字符串时,会强制转换为数字类型,遵守类型强制转换的规则。浮点数也是同样的道理,直接转换成了向下取整的整型。

那么"0.1"和"01"为什么还在?首先,"01"不是标准的十进制数值,无法转换成整型,所以"01"还是一个字符串下标,那"0.1"呢?它当然也不是一个标准的十进制数值。这里是违背了字符串转型数字的强制类型转换原则的,在变量的强制转换中,这两种字符串都会被转换为0,但在数组中则不会,这里会是一个坑,也是需要注意的地方。

在PHP官方文档中给出的Key值转换说明如下:

  • 包含有合法整型值的字符串会被转换为整型。例如键名 "8" 实际会被储存为 8。但是 "08" 则不会强制转换,因为其不是一个合法的十进制数值。
  • 浮点数也会被转换为整型,意味着其小数部分会被舍去。例如键名 8.7 实际会被储存为 8。
  • 布尔值也会被转换成整型。即键名 true 实际会被储存为 1 而键名 false 会被储存为 0。
  • Null 会被转换为空字符串,即键名 null 实际会被储存为 ""。
  • 数组和对象不能被用为键名。坚持这么做会导致警告:Illegal offset type。

接下来,是笔者曾经做过的一道面试题,和这个类型转换有着非常大的关系,代码如下:

a   = ['a'];
$a[2]  = 'b';
$a[]  = 'c';
$a['1'] = 'd';

// 以下循环的输出结果是?
foreach ($a as $v) {
	echo $v, ',';
}

// 以下循环的输出结果是?
for ($i = 0; $i < count($a); ++$i) {
	echo $a[$i], ' ,';
}

大家先不要运行,直接看代码看看能不能看出这两段代码的输出结果会是什么,然后运行一下,看看结果和你想像的是不是一样。

测试代码: https://github.com/zhangyue0503/dev-blog/blob/master/php/201910/source/关于PHP数组Key的强制转换.php

参考资料: https://www.php.net/manual/zh/language.types.array.php

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

PHP 相关文章推荐
杏林同学录(三)
Oct 09 PHP
怎么样可以把 phpinfo()屏蔽掉?
Nov 24 PHP
PHP 截取字符串专题集合
Aug 19 PHP
发款php蜘蛛统计插件只要有mysql就可用
Oct 12 PHP
PHP+SQL 注入攻击的技术实现以及预防办法
Dec 29 PHP
php获取表单中多个同名input元素的值
Mar 20 PHP
php发送与接收流文件的方法
Feb 11 PHP
php命令行(cli)下执行PHP脚本文件的相对路径的问题解决方法
May 25 PHP
php实现的网络相册图片防盗链完美破解方法
Jul 01 PHP
PHP邮箱验证示例教程
Jun 01 PHP
php引用和拷贝的区别知识点总结
Sep 23 PHP
PHP设计模式之组合模式定义与应用示例
Feb 01 PHP
Laravel中GraphQL接口请求频率实战记录
Sep 01 #PHP
PHP实现Snowflake生成分布式唯一ID的方法示例
Aug 30 #PHP
Yii实现微信公众号场景二维码的方法实例
Aug 30 #PHP
Swoole源码中如何查询Websocket的连接问题详解
Aug 30 #PHP
PHP常用header头定义代码示例汇总
Aug 29 #PHP
PHP isset()及empty()用法区别详解
Aug 29 #PHP
PHP实现简单日历类编写
Aug 28 #PHP
You might like
Apache 配置详解(最好的APACHE配置教程)
2010/07/04 PHP
php无限极分类递归排序实现方法
2014/11/11 PHP
php打印一个边长为N的实心和空心菱型的方法
2015/03/02 PHP
php给每个段落添加空格的方法
2015/03/20 PHP
PHP中把对象数组转换成普通数组的方法
2015/07/10 PHP
PHP中Enum(枚举)用法实例详解
2015/12/07 PHP
PHP手机号中间四位用星号*代替显示的实例
2017/06/02 PHP
PHP实现的操作数组类库定义与用法示例
2019/05/24 PHP
制作特殊字的脚本
2006/06/26 Javascript
jQuery EasyUI NumberBox(数字框)的用法
2010/07/08 Javascript
禁止页面刷新让F5快捷键及右键都无效
2014/01/22 Javascript
jQuery可见性过滤器:hidden和:visibility用法实例
2015/06/24 Javascript
详解JavaScript数组的操作大全
2015/10/19 Javascript
jQuery自定义滚动条完整实例
2016/01/08 Javascript
Bootstrap每天必学之日期控制
2016/03/07 Javascript
jQuery读取XML文件的方法示例
2017/02/03 Javascript
vue自定义移动端touch事件之点击、滑动、长按事件
2018/07/10 Javascript
PM2自动部署代码步骤流程总结
2018/12/10 Javascript
jquery操作select常见方法大全【7种情况】
2019/05/28 jQuery
Vue代码整洁之去重方法整理
2019/08/06 Javascript
JavaScript使用表单元素验证表单的示例代码
2019/08/20 Javascript
CountUp.js实现数字滚动增值效果
2019/10/17 Javascript
分享一款超好用的JavaScript 打包压缩工具
2020/04/26 Javascript
浅谈Vuex的this.$store.commit和在Vue项目中引用公共方法
2020/07/24 Javascript
Python ORM框架SQLAlchemy学习笔记之映射类使用实例和Session会话介绍
2014/06/10 Python
win系统下为Python3.5安装flask-mongoengine 库
2016/12/20 Python
关于python的bottle框架跨域请求报错问题的处理方法
2017/03/19 Python
windows下 兼容Python2和Python3的解决方法
2018/12/05 Python
python实现图片二值化及灰度处理方式
2019/12/07 Python
Pytorch学习之torch用法----比较操作(Comparison Ops)
2020/06/28 Python
《假如》教学反思
2014/04/17 职场文书
法律专业求职信
2014/05/24 职场文书
教师节活动总结
2014/08/29 职场文书
关于清明节的演讲稿
2014/09/13 职场文书
运动会广播稿200字
2014/10/18 职场文书
Python Pandas 删除列操作
2022/03/16 Python