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 相关文章推荐
在IIS上安装PHP4.0正式版
Oct 09 PHP
php巧获服务器端信息
Dec 06 PHP
php下载文件的代码示例
Jun 29 PHP
VIM中设置php自动缩进为4个空格的方法详解
Jun 14 PHP
php中调用其他系统http接口的方法说明
Feb 28 PHP
PHP面向对象程序设计之类常量用法实例
Aug 20 PHP
使用PHP和HTML5 FormData实现无刷新文件上传教程
Sep 06 PHP
PHP简单选择排序算法实例
Jan 26 PHP
php将数组存储为文本文件方法汇总
Oct 28 PHP
PHP面向对象多态性实现方法简单示例
Sep 27 PHP
PHP parse_ini_file函数的应用与扩展操作示例
Jan 07 PHP
php 使用expat方式解析xml文件操作示例
Nov 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文件上传类
2016/08/29 PHP
php写一个函数,实现扫描并打印出自定目录下(含子目录)所有jpg文件名
2017/05/26 PHP
PHP堆栈调试操作简单示例
2018/06/15 PHP
JavaScript 新手24条实用建议[TUTS+]
2009/06/21 Javascript
javascript 实用的文字链提示框效果
2010/06/30 Javascript
不用构造函数(Constructor)new关键字也能实现JavaScript的面向对象
2013/01/11 Javascript
js将long日期格式转换为标准日期格式实现思路
2013/04/07 Javascript
jquery实现不同大小浏览器使用不同的css样式表的方法
2014/04/02 Javascript
node.js中的fs.openSync方法使用说明
2014/12/17 Javascript
javascript异步编程代码书写规范Promise学习笔记
2015/02/11 Javascript
firefox浏览器用jquery.uploadify插件上传时报HTTP 302错误
2015/03/01 Javascript
jquery+CSS3实现3D拖拽相册效果
2016/07/18 Javascript
vue实现列表的添加点击
2016/12/29 Javascript
微信小程序 欢迎页面的制作(源码下载)
2017/01/09 Javascript
Angular开发实践之服务端渲染
2018/03/29 Javascript
vue计算属性computed的使用方法示例
2019/03/13 Javascript
vue实现移动端图片上传功能
2019/12/23 Javascript
Vue两个版本的区别和使用方法(更深层次了解)
2020/02/16 Javascript
JQuery复选框全选效果如何实现
2020/05/08 jQuery
通过python下载FTP上的文件夹的实现代码
2013/02/10 Python
django1.8使用表单上传文件的实现方法
2016/11/04 Python
Python实现简单过滤文本段的方法
2017/05/24 Python
python自动化脚本安装指定版本python环境详解
2017/09/14 Python
让代码变得更易维护的7个Python库
2018/10/09 Python
spyder 在控制台(console)执行python文件,debug python程序方式
2020/04/20 Python
python 实现rolling和apply函数的向下取值操作
2020/06/08 Python
python 提高开发效率的5个小技巧
2020/10/19 Python
Peter Alexander新西兰站:澳大利亚领先的睡衣设计师品牌
2016/12/10 全球购物
Needle & Thread官网:英国仙女品牌
2018/01/13 全球购物
size?瑞典:英国伦敦的球鞋精品店
2018/03/01 全球购物
澳大利亚和新西兰最大的在线旅行社之一:Aunt Betty
2019/08/07 全球购物
社会实践活动总结报告
2014/04/29 职场文书
2014年建筑工作总结
2014/11/26 职场文书
Python max函数中key的用法及原理解析
2021/06/26 Python
Java并发编程必备之Future机制
2021/06/30 Java/Android
一文弄懂MySQL索引创建原则
2022/02/28 MySQL