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 相关文章推荐
example1.php
Oct 09 PHP
NT IIS下用ODBC连接数据库
Oct 09 PHP
php中用于检测一个地理IP地址是否可用的代码
Feb 19 PHP
PHP中运用jQuery的Ajax跨域调用实现代码
Feb 21 PHP
Notice: Trying to get property of non-object problem(PHP)解决办法
Mar 11 PHP
PHP中extract()函数的妙用分析
Jul 11 PHP
详解 PHP加密解密字符串函数附源码下载
Dec 18 PHP
JSON字符串传到后台PHP处理问题的解决方法
Jun 05 PHP
PHP 与 UTF-8 的最佳实践详细介绍
Jan 04 PHP
Laravel 5使用Laravel Excel实现Excel/CSV文件导入导出的功能详解
Oct 11 PHP
PHP的PDO错误与错误处理
Jan 27 PHP
如何通过Apache在本地配置多个虚拟主机
Jul 29 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下封装较好的数字分页方法
2010/11/23 PHP
php自定义session示例分享
2014/04/22 PHP
浅谈本地WAMP环境的搭建
2015/05/13 PHP
PHP数组操作类实例
2015/07/11 PHP
100行PHP代码实现socks5代理服务器
2016/04/28 PHP
PHP基于简单递归函数求一个数阶乘的方法示例
2017/04/26 PHP
Laravel使用原生sql语句并调用的方法
2019/10/09 PHP
基于jquery &amp; json的省市区联动代码
2012/06/26 Javascript
js给dropdownlist添加选项的小例子
2013/03/04 Javascript
js定时器怎么写?就是在特定时间执行某段程序
2013/10/11 Javascript
JavaScript中setUTCFullYear()方法的使用简介
2015/06/12 Javascript
jQuery实现动画效果circle实例
2015/08/06 Javascript
基于MVC方式实现三级联动(JavaScript)
2017/01/23 Javascript
Vue实现动态创建和删除数据的方法
2018/03/17 Javascript
浅谈node.js 命令行工具(cli)
2018/05/10 Javascript
对angularJs中自定义指令replace的属性详解
2018/10/09 Javascript
详解vue中移动端自适应方案
2019/05/05 Javascript
Python中用pycurl监控http响应时间脚本分享
2015/02/02 Python
状态机的概念和在Python下使用状态机的教程
2015/04/11 Python
python 执行shell命令并将结果保存的实例
2018/05/11 Python
详解用python实现基本的学生管理系统(文件存储版)(python3)
2019/04/25 Python
Python日志syslog使用原理详解
2020/02/18 Python
详解css3 Transition属性(平滑过渡菜单栏案例)
2017/09/05 HTML / CSS
巴西电子、家电、智能手机购物网站:Girafa
2019/06/04 全球购物
英国排名第一的餐具品牌:Denby Pottery
2019/11/01 全球购物
巴西最大的巴士票务门户:Quero Passagem
2020/11/21 全球购物
如何用Java判断一个文件或目录是否存在
2012/11/19 面试题
网络研修随笔感言
2014/02/17 职场文书
保卫科工作岗位职责
2014/03/01 职场文书
建筑安全员岗位职责
2014/03/13 职场文书
电气工程及其自动化专业求职信
2014/06/23 职场文书
幼儿园个人总结
2015/02/28 职场文书
毕业生就业推荐表自我评价
2015/03/02 职场文书
七年级作文之英语老师
2019/10/28 职场文书
详解vue身份认证管理和租户管理
2021/05/25 Vue.js
阿里云服务器部署RabbitMQ集群的详细教程
2022/06/01 Servers