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中定义网站根目录的常用方法
Aug 08 PHP
php中OR与|| AND与&amp;&amp;的区别总结
Oct 26 PHP
ThinkPHP框架实现session跨域问题的解决方法
Jul 01 PHP
smarty模板判断数组为空的方法
Jun 10 PHP
搭建基于Docker的PHP开发环境的详细教程
Jul 01 PHP
[原创]PHP字符串中插入子字符串方法总结
May 06 PHP
PHP性能优化大全(php.ini)
May 20 PHP
linux下php上传文件注意事项
Jun 11 PHP
弹出模态框modal的实现方法及实例
Sep 19 PHP
PHP给源代码加密的几种方法汇总(推荐)
Feb 06 PHP
php使用lua+redis实现限流,计数器模式,令牌桶模式
Apr 04 PHP
PHP使用ActiveMQ实现消息队列的方法详解
May 31 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
IIS6.0+PHP5.x+MySQL5.x+Zend3.0x+GD+phpMyAdmin2.8x通用安装实例(已经完成)
2006/12/06 PHP
深入php-fpm的两种进程管理模式详解
2013/06/03 PHP
PHPstorm激活码2020年5月13日亲测有效
2020/09/17 PHP
javascript的onchange事件与jQuery的change()方法比较
2009/09/28 Javascript
浅析Prototype的模板类 Template
2011/12/07 Javascript
JS中批量给元素绑定事件过程中的相关问题使用闭包解决
2013/04/15 Javascript
探讨js字符串数组拼接的性能问题
2014/10/11 Javascript
ECMAScript5中的对象存取器属性:getter和setter介绍
2014/12/08 Javascript
JS+CSS实现淡入式焦点图片幻灯切换效果的方法
2015/02/26 Javascript
JavaScript面对国际化编程时的一些建议
2015/06/24 Javascript
JavaScript实现添加、查找、删除元素
2015/07/02 Javascript
jQuery中extend函数详解
2015/07/13 Javascript
js实现超简单的展开、折叠目录代码
2015/08/28 Javascript
JavaScript File分段上传
2016/03/10 Javascript
JS利用正则表达式实现简单的密码强弱判断实例
2017/06/16 Javascript
vue2.0中vue-cli实现全选、单选计算总价格的实例代码
2017/07/18 Javascript
vue项目部署到Apache服务器中遇到的问题解决
2018/08/24 Javascript
详解vue-cli3多页应用改造
2019/06/04 Javascript
如何基于filter实现网站整体变灰功能
2020/04/17 Javascript
[07:54]DOTA2-DPC中国联赛 正赛 iG vs VG 选手采访
2021/03/11 DOTA
在Python web中实现验证码图片代码分享
2017/11/09 Python
详谈Python3 操作系统与路径 模块(os / os.path / pathlib)
2018/04/26 Python
Python叠加两幅栅格图像的实现方法
2019/07/05 Python
django rest framework 自定义返回方式
2020/07/12 Python
浅谈CSS3中的变形功能-transform功能
2017/12/27 HTML / CSS
使用postMessage让 iframe自适应高度的方法示例
2019/10/08 HTML / CSS
澳大利亚在线床零售商:Bedworks
2020/09/01 全球购物
python+selenium小米商城红米K40手机自动抢购的示例代码
2021/03/24 Python
财务部岗位职责
2013/11/19 职场文书
公司门卫管理制度
2014/02/01 职场文书
教师读书活动总结
2014/05/07 职场文书
联谊活动总结
2014/08/28 职场文书
党支部考察鉴定意见
2015/06/02 职场文书
应届生们该怎么书写求职信?
2019/07/05 职场文书
Django项目如何获得SSL证书与配置HTTPS
2021/04/30 Python
SQL实战演练之网上商城数据库商品类别数据操作
2021/10/24 MySQL