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
php Xdebug 调试扩展的安装与使用.
Mar 13 PHP
PHP中文件上传的一个问题
Sep 04 PHP
php函数array_merge用法一例(合并同类数组)
Feb 03 PHP
php中AES加密解密的例子小结
Feb 18 PHP
php版淘宝网查询商品接口代码示例
Jun 17 PHP
基于OpenCart 开发支付宝,财付通,微信支付参数错误问题
Oct 01 PHP
PHP中的Trait 特性及作用
Apr 03 PHP
php反射学习之不用new方法实例化类操作示例
Jun 14 PHP
PHP利用DWZ.CN服务生成短网址
Aug 11 PHP
Laravel 连接(Join)示例
Oct 16 PHP
php中Swoole的热更新实现代码实例
Mar 04 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
Ajax+PHP 边学边练 之二 实例
2009/11/24 PHP
php实现的XML操作(读取)封装类完整实例
2017/02/23 PHP
Laravel实现autoload方法详解
2017/05/07 PHP
php在windows环境下获得cpu内存实时使用率(推荐)
2018/02/08 PHP
php-fpm添加service服务的例子
2018/04/27 PHP
理解 JavaScript 预解析
2009/10/25 Javascript
js修改table中Td的值(定义td的单击事件)
2013/01/10 Javascript
jquery 标签 隔若干行加空白或者加虚线的方法
2016/12/07 Javascript
javascript监听页面刷新和页面关闭事件方法详解
2017/01/09 Javascript
bootstrap table表格插件使用详解
2017/05/08 Javascript
JS中将多个逗号替换为一个逗号的实现代码
2017/06/23 Javascript
原生JS实现隐藏显示图片 JS实现点击切换图片效果
2021/01/27 Javascript
基于vue和react的spa进行按需加载的实现方法
2018/09/29 Javascript
微信小程序websocket聊天室的实现示例代码
2019/02/12 Javascript
vue+高德地图写地图选址组件的方法
2019/05/18 Javascript
Vue 实现前进刷新后退不刷新的效果
2019/06/14 Javascript
python查找指定具有相同内容文件的方法
2015/06/28 Python
18个Python脚本可加速你的编码速度(提示和技巧)
2019/10/17 Python
Python 开发工具PyCharm安装教程图文详解(新手必看)
2020/02/28 Python
打造经典复古风格的品牌:Alice + Olivia(爱丽丝+奥利维亚)
2016/09/07 全球购物
39美元购买一副眼镜或太阳镜:39DollarGlasses.com
2018/06/17 全球购物
MYSQL基础面试题
2012/05/13 面试题
医院学雷锋活动策划方案
2014/02/15 职场文书
《藤野先生》教学反思
2014/02/19 职场文书
社区学习雷锋活动总结
2014/04/25 职场文书
应届大学生求职信
2014/07/20 职场文书
北京天坛导游词
2015/02/12 职场文书
成事在人观后感
2015/06/16 职场文书
追悼会悼词大全
2015/06/23 职场文书
党纪处分决定书
2015/06/24 职场文书
酒桌上的祝酒词
2015/08/12 职场文书
2016高考寄语集锦
2015/12/04 职场文书
详解Redis集群搭建的三种方式
2021/05/31 Redis
Spring Boot 整合 Apache Dubbo的示例代码
2021/07/04 Java/Android
springboot 自定义配置 解决Boolean属性不生效
2022/03/18 Java/Android
Spring Security使用单点登录的权限功能
2022/04/03 Java/Android