PHP数组Key强制类型转换实现原理解析

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

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2020-08-30

php array_key_exists() 与 isset() 的区别

php array_key_exists用于检查某个键名是否存在于数组中,而isset也可以用于检测数组中某个键名是否存在,那么二者有什么区别呢?本文章将为大家讲解array_key_exists() 与 isset() 使用中的一些区别 一个基本的区别是isset()可用于数组和变量,而array_key_exits()只能用于数组. 但是最主要的区别在于在设定的条件下的返回值. 现在我们来验证一下这个最主要的区别. array_key_exists() array_key_exists()

PHP实现向关联数组指定的Key之前插入元素的方法

本文实例讲述了PHP实现向关联数组指定的Key之前插入元素的方法.分享给大家供大家参考,具体如下: PHP 关联数组可以通过三种方式插入新元素: 1. $array[$insert_key] = $insert_value; 2. $array = array_merge($array, $insert_array); 3. $array = $array+$insert_array; 但是如果要在指定的键之前插入元素呢?下面的代码将 $data 插入关联数组 $array 的键名为 $key

PHP使用自定义key实现对数据加密解密的方法

本文实例讲述了PHP使用自定义key实现对数据加密解密的方法.分享给大家供大家参考,具体如下: 客户端和服务端通信时,有个场景很常见,通过一个id作为url参数来回传递.假设现在业务上只有这个id标识,那么需要稍微安全一点的通信,对这个id进行加密传输,到服务端再进行解密.这里需要一个服务端进行保密的key,利用这个key进行加密和解密. 加解密的方法如下:$str是需要加解密的字符串,$key是自己定义的一个key // 加密 function encryptStr($str, $key){

PHP 根据key 给二维数组分组

我们经常拿到一个二维数组出来,会发现结果和自己想要的有些偏差,可能需要根据二维数组里的某个字段对数组分组. 先来看以下数组, Array ( [0] => Array ( [id] => 1 [wo_id] => 2 [evaluate_id] => 1 [type] => 分组1 [ctime] => 2016-12-02 11:39:34 ) [1] => Array ( [id] => 2 [wo_id] => 31 [evaluate_id]

PHP实现二维数组根据key进行排序的方法

本文实例讲述了PHP实现二维数组根据key进行排序的方法.分享给大家供大家参考,具体如下: 在PHP中内置了很多对数组进行处理的函数,有很多时候我们直接使用其内置函数就能达到我们的需求,得到我们所想要的结果:但是,有的时候我们却不能通过使用内置函数实现我们的要求,这就需要我们自己去编写算法来对自己的想法进行实现.下面就讲述一下如何实现二维数组根据key进行排序. 实现方法: <?php /** * ======================================= * Created

PHP根据key删除数组中指定的元素

php数组中元素的存在方式是以键值对的方式('key'=>'value'),有时候我们需要根据键删除数组中指定的某个元素. function bykey_reitem($arr, $key){ if(!array_key_exists($key, $arr)){ return $arr; } $keys = array_keys($arr); $index = array_search($key, $keys); if($index !== FALSE){ array_splice($arr,

php array_keys 返回数组的键名

array_keys返回数组中部分的或所有的键名 说明 array array_keys ( array $array [, mixed $search_value [, bool $strict = false ]] ) array_keys() 返回 $array 数组中的数字或者字符串的键名. 如果指定了可选参数 search_value,则只返回该值的键名.否则 $array 数组中的所有键名都会被返回. 参数详解 参数 描述 array 必需.一个数组,包含了要返回的键. search

PHP array_key_exists检查键名或索引是否存在于数组中的实现方法

array_key_exists() PHP array_key_exists() 函数用于检查给定的键名或索引是否存在于数组中,如果存在则返回 TRUE ,否则返回 FALSE . 语法: bool array_key_exists( mixed key, array search )参数 key 是给定的键名或索引,可以是任何能作为数组索引的值. array_key_exists() 函数也可用于对象. 例子: <?php $arr_a = array('id' => 1, 'name'

php二维数组用键名分组相加实例函数

本文介绍一篇关于php 二维数组以某一键名进行分组相加的实例程序,如果是从数据库里取数据的时候大可以SELECT SUM(t_value),t_id FROM t_table GROUP BY t_id,但是如果是在php程序中处理类似的问题就稍微麻烦点了,这里给个函数就是处理类似的问题 复制代码 代码如下: <?php /* 函数功能:对二维数组以某一键名进行分组相加,返回新的二维数组  * 参数说明:$arr-源数组:$new_arr-相加后得到的新数组:$target_key-要分组的键名

php数组函数序列之array_flip() 将数组键名与值对调

array_flip() 定义和用法 array_flip() 函数将使数组的键名与其相应值调换,即键名变成了值,而值变成了键名. array_flip() 函数返回一个反转后的数组,如果同一值出现了多次,则最后一个键名将作为它的值,所有其他的键名都将丢失. 如果原数组中的值的数据类型不是字符串或整数,函数将报错. 语法 array_flip(array)参数 描述 array 必需.规定输入的数组. 例子 复制代码 代码如下: <?php $a=array(0=>"Dog"

php数组函数序列之array_key_exists() - 查找数组键名是否存在

array_key_exists() 定义和用法 array_key_exists() 函数判断某个数组中是否存在指定的 key,如果该 key 存在,则返回 true,否则返回 false. 语法 array_key_exists(key,array) 参数 描述 key 必需.规定键名. array 必需.规定输入的数组. 例子 1 复制代码 代码如下: <?php $a=array("a"=>"Dog","b"=>&quo

php数组函数序列之ksort()对数组的元素键名进行升序排序,保持索引关系

ksort()定义和用法 ksort() 函数按照键名对数组升序排序,为数组值保留原来的键. 可选的第二个参数包含附加的排序标志. 若成功,则返回 TRUE,否则返回 FALSE. 语法 ksort(array,sorttype)参数 描述 array 必需.规定要排序的数组. sorttype 可选.规定如何排列数组的值.可能的值: SORT_REGULAR - 默认.以它们原来的类型进行处理(不改变类型). SORT_NUMERIC - 把值作为数字来处理 SORT_STRING - 把值作

php数组函数序列之array_keys() - 获取数组键名

array_keys() 定义和用法 array_keys() 函数返回包含数组中所有键名的一个新数组. 如果提供了第二个参数,则只返回键值为该值的键名. 如果 strict 参数指定为 true,则 PHP 会使用全等比较 (===) 来严格检查键值的数据类型. 语法 array_keys(array,value) 参数 描述 array 必需.规定输入的数组. value 可选.指定值的索引(键). strict 可选.与 value 参数一起使用.可能的值: true - 根据类型返回带有

php在多维数组中根据键名快速查询其父键以及父键值的代码

我这么想的: 遍历一遍多维数组,将所有的键建立索引生成一个一维数组: 每次通过键名去查这个键的上级数组及数据 OK,代码如下 indexKey创建索引数组函数: 复制代码 代码如下: <?php /** * FILE_NAME : arr.php FILE_PATH : test/ * 在多维数组中根据键名快速查询其父键以及父键值 * * @copyright Copyright (c) 2006-2010 mail:levi@cgfeel.com * @author Levi * @packa

PHP实现二维数组按指定的键名排序的方法示例

本文实例讲述了PHP实现二维数组按指定的键名排序的方法.分享给大家供大家参考,具体如下: <?php /*二维数组按指定的键值排序*/ function array_sort($array,$keys,$type='asc'){ if(!isset($array) || !is_array($array) || empty($array)){ return ''; } //排序字段名,如:id if(!isset($keys) || trim($keys)==''){ return ''; }

php数组函数序列之array_search()- 按元素值返回键名

array_search()定义和用法 array_search() 函数与 in_array() 一样,在数组中查找一个键值.如果找到了该值,匹配元素的键名会被返回.如果没找到,则返回 false. 在 PHP 4.2.0 之前,函数在失败时返回 null 而不是 false. 如果第三个参数 strict 被指定为 true,则只有在数据类型和值都一致时才返回相应元素的键名. 语法 array_search(value,array,strict)参数 描述 value 必需.规定在数组中搜索

PHP中替换键名的简易方法示例详解

YII框架中封装好了的数据库操作函数,默认输出的时候,将数据库字段名作为数组的键名进行输出,但是有些时候带有键名的数据不能够满足未知情况下的操作,譬如:数据库数据导出为EXCEL等比较非正常的操作. 所以这边需要对数据库结果集进行解析,下面就是针对这种特殊情况的一个简单方法: 复制代码 代码如下: /** * @todo 针对YII 查询输出带有数据库表字段名键名进行优化EXCEL表格输出 * @todo 替换键名为0.1.2... * @param array $data * @return