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 相关文章推荐
实用函数3
Nov 08 PHP
php Smarty date_format [格式化时间日期]
Mar 15 PHP
Windows下XDebug 手工配置与使用说明
Jul 11 PHP
php实现utf-8和GB2312编码相互转换函数代码
Feb 07 PHP
360通用php防护代码(使用操作详解)
Jun 18 PHP
基于php的微信公众平台开发入门实例
Apr 15 PHP
PHP5.2中PDO的简单使用方法
Mar 25 PHP
PHP使用自定义方法实现数组合并示例
Jul 07 PHP
遍历echsop的region表形成缓存的程序实例代码
Nov 01 PHP
laravel框架实现敏感词汇过滤功能示例
Feb 15 PHP
php 多进程编程父进程的阻塞与非阻塞实例分析
Feb 22 PHP
php中加密解密DES类的简单使用方法示例
Mar 26 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 删除记录实现代码
2009/03/12 PHP
php download.php实现代码 跳转到下载文件(response.redirect)
2009/08/26 PHP
理解php Hash函数,增强密码安全
2011/02/25 PHP
php中addslashes函数与sql防注入
2014/11/17 PHP
PHP使用strrev翻转中文乱码问题的解决方法
2017/01/13 PHP
鼠标滑上去后图片放大浮出效果的js代码
2011/05/28 Javascript
基于jquery ui的alert,confirm方案(支持换肤)
2015/04/03 Javascript
jquery实现的点击翻书效果代码
2015/11/04 Javascript
JS Canvas定时器模拟动态加载动画
2016/09/17 Javascript
浅谈jquery高级方法描述与应用
2016/10/04 Javascript
浅谈js中同名函数和同名变量的执行问题
2017/02/12 Javascript
JavaScript实现父子dom同时绑定两个点击事件,一个用捕获,一个用冒泡时执行顺序的方法
2017/03/30 Javascript
Vue组件中slot的用法
2018/01/30 Javascript
vue实现简单的MVVM框架
2018/08/05 Javascript
Vue CLI3 开启gzip压缩文件的方式
2018/09/30 Javascript
NodeJs 模仿SIP话机注册的方法
2019/06/21 NodeJs
微信小程序自定义顶部组件customHeader的示例代码
2020/06/03 Javascript
vue实例的选项总结
2020/06/09 Javascript
最基础的Python的socket编程入门教程
2015/04/23 Python
教你学会使用Python正则表达式
2017/09/07 Python
Python管理Windows服务小脚本
2018/03/12 Python
详解tensorflow载入数据的三种方式
2018/04/24 Python
python程序 线程队列queue使用方法解析
2019/09/23 Python
Python hashlib模块的使用示例
2020/10/09 Python
Python如何急速下载第三方库详解
2020/11/02 Python
python解包用法详解
2021/02/17 Python
CSS3绘制有活力的链接下划线
2016/07/14 HTML / CSS
HTML5的download属性详细介绍和使用实例
2014/04/23 HTML / CSS
英国领先的运动物理治疗供应公司:Vivomed
2018/07/14 全球购物
.net工程师笔试题
2012/06/09 面试题
和谐家庭演讲稿
2014/05/24 职场文书
公司离职证明标准范本
2014/10/05 职场文书
Go 实现英尺和米的简单单位换算方式
2021/04/29 Golang
如何使用Python提取Chrome浏览器保存的密码
2021/06/09 Python
P站美图推荐——变身女主角特辑
2022/03/20 日漫
SQLyog的下载、安装、破解、配置教程(MySQL可视化工具安装)
2022/09/23 MySQL