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&amp;mysql(二)
Oct 09 PHP
php empty函数 使用说明
Aug 10 PHP
查找php配置文件php.ini所在路径的二种方法
May 26 PHP
PHP列出MySQL中所有数据库的方法
Mar 12 PHP
php实现Mongodb自定义方式生成自增ID的方法
Mar 23 PHP
制作个性化的WordPress登陆界面的实例教程
May 21 PHP
PHP数组生成XML格式数据的封装类实例
Nov 10 PHP
php实现与python进行socket通信的方法示例
Aug 30 PHP
thinkPHP5实现数据库添加内容的方法
Oct 25 PHP
Yii框架Session与Cookie使用方法示例
Oct 14 PHP
4种Windows系统下Laravel框架的开发环境安装及部署方法详解
Apr 06 PHP
PHP7 其他修改
Mar 09 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中实现简单的ACL 完结篇
2011/09/07 PHP
解析PHP中的file_get_contents获取远程页面乱码的问题
2013/06/25 PHP
php中生成随机密码的自定义函数代码
2013/10/21 PHP
2014年最新推荐的10款 PHP 开发框架
2014/08/01 PHP
PHP页面转UTF-8中文编码乱码的解决办法
2015/10/20 PHP
PHP MPDF中文乱码的解决方式
2015/12/08 PHP
使用CSS3实现字体颜色渐变的实现
2021/03/09 HTML / CSS
Javascript前端UI框架Kit使用指南之kitjs的对话框组件
2014/11/28 Javascript
EasyUi中的Combogrid 实现分页和动态搜索远程数据
2016/04/01 Javascript
JS简单测试循环运行时间的方法
2016/09/04 Javascript
nodeJS实现路由功能实例代码
2017/06/08 NodeJs
各种选择框jQuery的选中方法(实例讲解)
2017/06/27 jQuery
浅谈vuex 闲置状态重置方案
2018/01/04 Javascript
jQuery实现滚动到底部时自动加载更多的方法示例
2018/02/18 jQuery
nodejs简单访问及操作mysql数据库的方法示例
2018/03/15 NodeJs
Vue父子组件之间的通信实例详解
2018/09/28 Javascript
vue router 用户登陆功能的实例代码
2019/04/24 Javascript
jquery操作checkbox的常用方法总结【附测试源码下载】
2019/06/10 jQuery
Node.js实现简单管理系统
2019/09/23 Javascript
AngularJs的$http发送POST请求,php无法接收Post的数据问题及解决方案
2020/08/13 Javascript
[01:13]这,就是刀塔
2014/07/16 DOTA
Ruby使用eventmachine为HTTP服务器添加文件下载功能
2016/04/20 Python
Python SQLite3数据库日期与时间常见函数用法分析
2017/08/14 Python
django静态文件加载的方法
2018/05/20 Python
python控制windows剪贴板,向剪贴板中写入图片的实例
2018/05/31 Python
Python API 自动化实战详解(纯代码)
2019/06/11 Python
Python3.6 + TensorFlow 安装配置图文教程(Windows 64 bit)
2020/02/24 Python
python打包生成so文件的实现
2020/10/30 Python
一款纯css3实现的鼠标经过按钮特效教程
2014/11/09 HTML / CSS
卡西欧B级产品官方网站:Casio Outlet
2018/05/22 全球购物
医院护士见习期自我鉴定
2014/04/10 职场文书
捐款倡议书
2014/04/14 职场文书
2014年业务员工作总结范文
2014/11/17 职场文书
小学三年级班主任工作经验交流材料
2015/11/02 职场文书
Python实现Telnet自动连接检测密码的示例
2021/04/16 Python
vue 数字翻牌器动态加载数据
2022/04/20 Vue.js