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 01 PHP
php不用内置函数对数组排序的两个算法代码
Feb 08 PHP
php下关于中英数字混排的字符串分割问题
Apr 06 PHP
PHP 自定义错误处理函数的使用详解
May 10 PHP
PHP中的函数-- foreach()的用法详解
Jun 24 PHP
PHP反向代理类代码
Aug 15 PHP
PHP中soap的用法实例
Oct 24 PHP
PHP概率计算函数汇总
Sep 13 PHP
fsockopen pfsockopen函数被禁用,SMTP发送邮件不正常的解决方法
Sep 20 PHP
php 计算两个时间相差的天数、小时数、分钟数、秒数详解及实例代码
Nov 09 PHP
PHP实现的观察者模式实例
Jun 21 PHP
PHP生成腾讯云COS接口需要的请求签名
May 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
PHP简单系统查询模块代码打包下载
2008/06/07 PHP
PHP写UltraEdit插件脚本实现方法
2011/12/26 PHP
PHP实现变色验证码实例
2014/01/06 PHP
Laravel框架中自定义模板指令总结
2017/12/17 PHP
Laravel框架在本地虚拟机快速安装的方法详解
2018/06/11 PHP
php对象工厂类完整示例
2018/08/09 PHP
PHP哈希表实现算法原理解析
2020/12/11 PHP
用js+xml自动生成表格的东西
2006/12/21 Javascript
用JavaScript事件串连执行多个处理过程的方法
2007/03/09 Javascript
js 取时间差去掉周六周日实现代码
2012/12/25 Javascript
jquery复选框checkbox实现删除前判断
2014/04/20 Javascript
javascript操作excel生成报表全攻略
2014/05/04 Javascript
jQuery焦点图切换简易插件制作过程全纪录
2014/08/27 Javascript
打造个性化的功能强大的Jquery虚拟键盘(VirtualKeyboard)
2014/10/11 Javascript
JavaScript插件化开发教程 (二)
2015/01/27 Javascript
jQuery带时间的日期控件代码分享
2015/08/26 Javascript
利用jquery制作滚动到指定位置触发动画
2016/03/26 Javascript
jQuery实现下拉框左右移动(全部移动,已选移动)
2016/04/15 Javascript
JavaScript中的 attribute 和 jQuery中的 attr 方法浅析
2017/01/04 Javascript
在vue项目中正确使用iconfont的方法
2018/09/28 Javascript
[49:54]Ti4 循环赛第三日 LGD vs Titan
2014/07/12 DOTA
Python设计模式之工厂模式简单示例
2018/01/09 Python
python实现机器人行走效果
2018/01/29 Python
python自动重试第三方包retrying模块的方法
2018/04/24 Python
python使用numpy读取、保存txt数据的实例
2018/10/14 Python
Django重置migrations文件的方法步骤
2019/05/01 Python
python将字符串转变成dict格式的实现
2019/11/18 Python
Python使用QQ邮箱发送邮件报错smtplib.SMTPAuthenticationError
2019/12/20 Python
Python 日期的转换及计算的具体使用详解
2020/01/16 Python
python 30行代码实现蚂蚁森林自动偷能量
2021/02/08 Python
人力资源管理专业应届生求职信
2013/09/28 职场文书
行政工作个人的自我评价
2014/02/13 职场文书
体育专业求职信
2014/07/16 职场文书
供应商食品安全承诺书
2015/04/29 职场文书
CSS中em的正确打开方式详解
2021/04/08 HTML / CSS
JS前端canvas交互实现拖拽旋转及缩放示例
2022/08/05 Javascript