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 相关文章推荐
php中的时间显示
Jan 18 PHP
php数组总结篇(一)
Sep 30 PHP
zend api扩展的php对象的autoload工具
Apr 18 PHP
PHP curl 并发最佳实践代码分享
Sep 05 PHP
PHP CodeBase:将时间显示为&quot;刚刚&quot;&quot;n分钟/小时前&quot;的方法详解
Jun 06 PHP
探讨:如何编写PHP扩展
Jun 13 PHP
PHP中source #N问题的解决方法
Jan 27 PHP
php实现的CSS更新类实例
Sep 22 PHP
thinkphp3.2.3 分页代码分享
Jul 28 PHP
PHP上传图片时判断上传文件是否为可用图片的方法
Oct 20 PHP
PHP压缩图片功能的介绍
Mar 21 PHP
ThinkPHP3.2框架自带分页功能实现方法示例
May 13 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
一个程序下载的管理程序(三)
2006/10/09 PHP
PHP文件打开、关闭、写入的判断与执行代码
2011/05/24 PHP
php防止sql注入之过滤分页参数实例
2014/11/03 PHP
laravel 5 实现模板主题功能
2015/03/02 PHP
php将数组转换成csv格式文件输出的方法
2015/03/14 PHP
PHP 中 Orientation 属性判断上传图片是否需要旋转
2015/10/16 PHP
Symfony2在Nginx下的配置方法图文教程
2016/02/04 PHP
PHP处理数组和XML之间的互相转换
2016/06/02 PHP
JavaScript方法和技巧大全
2006/12/27 Javascript
Javascript实现的分页函数
2007/02/07 Javascript
Jquery CheckBox全选方法代码附js checkbox全选反选代码
2010/06/09 Javascript
jquery插件lazyload.js延迟加载图片的使用方法
2014/02/19 Javascript
jQuery中before()方法用法实例
2014/12/25 Javascript
javascript实现可全选、反选及删除表格的方法
2015/05/15 Javascript
JS简单实现浮动窗口效果示例
2016/09/07 Javascript
Jquery Easyui日历组件Calender使用详解(23)
2016/12/18 Javascript
详解js产生对象的3种基本方式(工厂模式,构造函数模式,原型模式)
2017/01/09 Javascript
微信小程序登录态控制深入分析
2017/04/12 Javascript
JavaScript原生实现观察者模式的示例
2017/12/15 Javascript
微信小程序自定义toast弹窗效果的实现代码
2018/11/15 Javascript
vuex实现像调用模板方法一样调用Mutations方法
2019/11/06 Javascript
微信小程序实现加入购物车滑动轨迹
2020/11/18 Javascript
[40:48]DOTA2上海特级锦标赛D组败者赛 Liquid VS COL第二局
2016/02/28 DOTA
mac下如何将python2.7改为python3
2018/07/13 Python
python os.listdir按文件存取时间顺序列出目录的实例
2018/10/21 Python
在python里从协程返回一个值的示例
2019/02/19 Python
python 利用文件锁单例执行脚本的方法
2019/02/19 Python
PyQtGraph在pyqt中的应用及安装过程
2019/08/04 Python
L’AGENCE官网:加州女装品牌
2018/06/03 全球购物
两道JAVA笔试题
2016/09/14 面试题
致全体运动员广播稿
2014/02/01 职场文书
桥梁工程专业求职信
2014/04/21 职场文书
关爱留守儿童标语
2014/06/18 职场文书
2016年中秋节晚会领导致辞
2015/11/26 职场文书
在python中实现导入一个需要传参的模块
2021/05/12 Python
利用Python实现Picgo图床工具
2021/11/23 Python