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 相关文章推荐
GD输出汉字的函数的分析
Oct 09 PHP
php中经典方法实现判断多维数组是否为空
Oct 23 PHP
PHP重定向的3种方式
Mar 07 PHP
PHP常用函数和常见疑难问题解答
Mar 05 PHP
thinkphp模板的包含与渲染实例分析
Nov 26 PHP
PHP测试成功的邮件发送案例
Oct 26 PHP
PHP二维数组去重算法
Dec 17 PHP
php如何实现不借助IDE快速定位行数或者方法定义的文件和位置
Jan 17 PHP
YII框架批量插入数据的方法
Mar 18 PHP
PHP实现的迪科斯彻(Dijkstra)最短路径算法实例
Sep 16 PHP
使用PHPExcel导出Excel表
Sep 08 PHP
php微信公众号开发之图片回复
Oct 20 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
全国FM电台频率大全 - 18 湖南省
2020/03/11 无线电
Yii2框架中一些折磨人的坑
2019/12/15 PHP
漂亮的widgets,支持换肤和后期开发新皮肤(2007-4-27已更新1.7alpha)
2007/04/27 Javascript
jquery中获取元素的几种方式小结
2011/07/05 Javascript
JS 操作符整理[推荐收藏]
2011/11/15 Javascript
手机端网页点击链接触发自动拨打或保存电话的示例代码
2014/08/15 Javascript
js同源策略详解
2015/05/21 Javascript
JavaScript中cookie工具函数封装的示例代码
2016/10/11 Javascript
谈谈JS中的!!
2017/12/07 Javascript
浅谈react受控组件与非受控组件(小结)
2018/02/09 Javascript
mint-ui 时间插件使用及获取选择值的方法
2018/02/09 Javascript
代码详解javascript模块加载器
2018/03/04 Javascript
再谈Angular4 脏值检测(性能优化)
2018/04/23 Javascript
layui自己添加图片按钮并点击跳转页面的例子
2019/09/14 Javascript
解决微信小程序中的滚动穿透问题
2019/09/16 Javascript
vue实现全匹配搜索列表内容
2019/09/26 Javascript
vue使用原生swiper代码实例
2020/02/05 Javascript
[01:07:02]DOTA2-DPC中国联赛 正赛 iG vs PSG.LGD BO3 第三场 2月26日
2021/03/11 DOTA
仅用500行Python代码实现一个英文解析器的教程
2015/04/02 Python
Python压缩解压缩zip文件及破解zip文件密码的方法
2015/11/04 Python
Python实现的简单模板引擎功能示例
2017/09/02 Python
Python中eval带来的潜在风险代码分析
2017/12/11 Python
《与孩子一起学编程》python自测题
2018/05/27 Python
Django REST Framework序列化外键获取外键的值方法
2019/07/26 Python
python matplotlib拟合直线的实现
2019/11/19 Python
Python可变对象与不可变对象原理解析
2020/02/25 Python
详解python 条件语句和while循环的实例代码
2020/12/28 Python
Python基于argparse与ConfigParser库进行入参解析与ini parser
2021/02/02 Python
意大利奢华内衣制造商:Cosabella
2017/08/29 全球购物
世界上最值得信赖的多日游在线市场:TourRadar
2018/07/20 全球购物
微软加拿大官方网站:Microsoft Canada
2019/04/28 全球购物
学院领导推荐信
2013/10/30 职场文书
大二学生职业生涯规划书
2014/02/05 职场文书
项目采购员岗位职责
2014/04/15 职场文书
学校学习型党组织建设心得体会
2019/06/21 职场文书
Redis特殊数据类型bitmap位图
2022/06/01 Redis