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集成FCK的函数代码
Sep 27 PHP
全世界最小的php网页木马一枚 附PHP木马的防范方法
Oct 09 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
Jan 11 PHP
如何给phpcms v9增加类似于phpcms 2008中的关键词表
Jul 01 PHP
smarty缓存用法分析
Dec 16 PHP
php检测url是否存在的方法
Apr 14 PHP
学习php设计模式 php实现备忘录模式(Memento)
Dec 09 PHP
深入浅出讲解:php的socket通信原理
Dec 03 PHP
PHP convert_cyr_string()函数讲解
Feb 13 PHP
PHP实现的操作数组类库定义与用法示例
May 24 PHP
php统计数组不同元素的个数的实例方法
Sep 26 PHP
thinkPHP框架乐观锁和悲观锁实例分析
Oct 30 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
关于file_get_contents返回为空或函数不可用的解决方案
2013/06/24 PHP
thinkphp中字符截取函数msubstr()用法分析
2016/01/09 PHP
php安装dblib扩展,连接mssql的具体步骤
2017/03/02 PHP
PHP 图片合成、仿微信群头像的方法示例
2019/10/25 PHP
文本加密解密
2006/06/23 Javascript
Js event事件在IE、FF兼容性问题
2011/01/01 Javascript
70+漂亮且极具亲和力的导航菜单设计国外网站推荐
2011/09/20 Javascript
Javascript浅谈之引用类型
2013/12/18 Javascript
javascript表单验证和Window详解
2014/12/11 Javascript
JS实现的仿QQ空间图片弹出效果代码
2016/02/23 Javascript
JavaScript利用闭包实现模块化
2017/01/13 Javascript
基于JavaScript实现自定义滚动条
2017/01/25 Javascript
JS中图片压缩的方法小结
2017/11/14 Javascript
如何在 JavaScript 中更好地利用数组
2018/09/27 Javascript
Vue.js结合bootstrap前端实现分页和排序效果
2018/12/29 Javascript
详解Vuex下Store的模块化拆分实践
2019/07/31 Javascript
通过扫小程序码实现网站登陆功能
2019/08/22 Javascript
使用Bootstrap做一个朝代历史表
2019/12/10 Javascript
[01:17]辉夜杯战队访谈宣传片—EHOME
2015/12/25 DOTA
Python中的Classes和Metaclasses详解
2015/04/02 Python
Python实现统计英文单词个数及字符串分割代码
2015/05/28 Python
Django自定义用户认证示例详解
2018/03/14 Python
78行Python代码实现现微信撤回消息功能
2018/07/26 Python
Python 抓取微信公众号账号信息的方法
2019/06/14 Python
浅谈keras使用预训练模型vgg16分类,损失和准确度不变
2020/07/02 Python
eDreams巴西:廉价机票,酒店优惠和度假套餐
2017/04/14 全球购物
函授本科毕业自我鉴定
2013/10/09 职场文书
青春奉献演讲稿
2014/05/08 职场文书
讲文明知礼仪演讲稿
2014/09/13 职场文书
干部个人考察材料
2014/12/24 职场文书
导游词300字
2015/02/13 职场文书
2015年学校医务室工作总结
2015/07/20 职场文书
家庭聚会祝酒词
2015/08/11 职场文书
《倍数和因数》教学反思
2016/02/23 职场文书
上帝为你开了一扇窗之Tkinter常用函数详解
2021/06/02 Python
CSS控制继承中的height能变为可继承吗
2022/06/10 HTML / CSS