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的中问验证码
Nov 25 PHP
PHP读取目录下所有文件的代码
Jan 07 PHP
让PHP以ROOT权限执行系统命令的方法
Feb 10 PHP
php实现利用phpexcel导出数据
Aug 24 PHP
PHP中一些可以替代正则表达式函数的字符串操作函数
Nov 17 PHP
php利用cookies实现购物车的方法
Dec 10 PHP
php安装swoole扩展的方法
Mar 19 PHP
基于PHP技术开发客服工单系统
Jan 06 PHP
Zend Framework框架教程之Zend_Db_Table_Rowset用法实例分析
Mar 21 PHP
phpinfo()中Loaded Configuration File(none)的解决方法
Jan 16 PHP
PHP智能识别收货地址信息实例
Jan 05 PHP
php装饰者模式简单应用案例分析
Oct 23 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的String类代码
2010/04/20 PHP
Laravel如何自定义command命令浅析
2019/03/23 PHP
js png图片(有含有透明)在IE6中为什么不透明了
2010/02/07 Javascript
jquery validate poshytip 自定义样式
2012/11/26 Javascript
jQuery中filter()和find()的区别深入了解
2013/09/25 Javascript
javascript对下拉列表框(select)的操作实例讲解
2013/11/29 Javascript
JS控制图片等比例缩放的示例代码
2013/12/24 Javascript
使用jquery实现以post打开新窗口
2014/03/19 Javascript
用JavaScript判断CSS浏览器类型前缀的两种方法
2015/10/08 Javascript
JavaScript、jQuery与Ajax的关系
2016/01/24 Javascript
vue生成随机验证码的示例代码
2017/09/29 Javascript
vue jsx 使用指南及vue.js 使用jsx语法的方法
2017/11/11 Javascript
vuejs实现递归树型菜单组件
2018/01/13 Javascript
微信小程序开发技巧汇总
2019/07/15 Javascript
微信小程序tabBar 返回tabBar不刷新页面
2019/07/25 Javascript
python基础教程之数字处理(math)模块详解
2014/03/25 Python
Python 检查数组元素是否存在类似PHP isset()方法
2014/10/14 Python
python使用点操作符访问字典(dict)数据的方法
2015/03/16 Python
使用Python中的cookielib模拟登录网站
2015/04/09 Python
Python实现简单的文本相似度分析操作详解
2018/06/16 Python
解决python明明pip安装成功却找不到包的问题
2019/08/28 Python
基于Python实现船舶的MMSI的获取(推荐)
2019/10/21 Python
Pycharm IDE的安装和使用教程详解
2020/04/30 Python
Python如何把字典写入到CSV文件的方法示例
2020/08/23 Python
西班牙拥有最佳品牌的动物商店:Animalear.com
2018/01/05 全球购物
Piercing Pagoda官网:耳环、戒指、项链、手链等
2020/09/28 全球购物
北京一家公司的.net开发工程师笔试题
2012/04/17 面试题
品管员岗位职责
2013/11/10 职场文书
初中教师业务学习材料
2014/05/12 职场文书
生物工程专业求职信
2014/09/03 职场文书
四风之害观后感
2015/06/09 职场文书
手把手教你使用TensorFlow2实现RNN
2021/07/15 Python
springboot集成springCloud中gateway时启动报错的解决
2021/07/16 Java/Android
Win2008系统搭建DHCP服务器
2022/06/25 Servers
Nginx跨域问题解析与解决
2022/08/05 Servers
教你使用RustDesk 搭建一个自己的远程桌面中继服务器
2022/08/14 Servers