002. PHP 8.1 更新之数组:解包数组和 array_is_list 函数

本视频源码 github.com/LearnKu-LX4/001_005_php...

说明

大家好,这个视频我来演示下 PHP 8.1 数组相关的两个特性,解包数组和 array_is_list 函数。

1. 解包数组

8.1 之前

PHP 版本 7.4 已经支持数组解包,laravelplayground.com/#/ 代码如下:

<?php 

$array_1 = ['foo', 'bar'];
$array_2 = ['baz', 'qux'];

$array_unpacked = [...$array_1, ...$array_2, ...['quux']];
$array_merged   = array_merge($array_1, $array_2, ['quux']);

dump($array_unpacked);
// ['foo', 'bar', 'baz', 'qux', 'quux'];

dump($array_merged);
// ['foo', 'bar', 'baz', 'qux', 'quux'];

exit;

可以看到解包数组跟 array_merge() 的结果是一样的:

不过 7.4 只支持不带键键数组,例如 8.0 的代码里,如果以下:

<?php

$array_1 = [
    'key1' => 'foo', 
    'key2' => 'bar'
];
$array_2 = [
    'key3' => 'baz', 
    'key4' => 'qux'
];

$array_unpacked = [...$array_1, ...$array_2];
dd($array_unpacked);

会出现报错:

Error
Cannot unpack array with string keys

8.1 支持二维数组

在 PHP 8.1 里 laravelplayground.com/#/?php=81 ,运行同样的代码,可以成功返回:

array:4 ["key1" => "foo"
  "key2" => "bar"
  "key3" => "baz"
  "key4" => "qux"
]

解包数组和 array_merge 的区别

<?php

$array_1 = [
    'key1' => 'foo', 
    'key2' => 'bar'
];
$array_2 = [
    'key3' => 'baz', 
    'key4' => 'qux'
];

$array_unpacked = [...$array_1, ...$array_2];
$array_merged   = array_merge($array_1, $array_2);

dd($array_merged == $array_unpacked);

他们的结果是一样的,以上代码返回:

true

解包数组和 + 操作符


dump(
    ['same_key' => 'value1']
   +['same_key' => 'value2']
);

dump([
    ...['same_key' => 'value1'],
    ...['same_key' => 'value2']
]);

加号运算符会跳过相同 Key 的值,而解包数组会覆盖相同 Key 的值:

// + 运算符
array:1 ["same_key" => "value1"
]

// 解包数组
array:1 ["same_key" => "value2"
]

2. 新增的 array_is_list() 方法

PHP 8.1 新增了一个 array_is_list 来判断是否是从 0 开始递增的数字数组。

也就是说,如果是从 0 开始递增的数字数组,会返回 true:

echo("array_is_list([1, 2, 3]):");
dump(array_is_list([1, 2, 3]));

echo("array_is_list(['apple', 'orange']):");
dump(array_is_list(['apple', 'orange']));

echo("array_is_list(['apple', 2, 3]):");
dump(array_is_list(['apple', 2, 3]));

echo("array_is_list([0 => 'apple', 'orange']):");
dump(array_is_list([0 => 'apple', 'orange']));

echo("array_is_list([0 => 'apple', 1 => 'orange']):");
dump(array_is_list([0 => 'apple', 1 => 'orange']));

以上全部返回 true。

另外需要注意的是,如果为空数组,也会返回 true

dump(array_is_list([]));

下面的例子全部返回 false:

// Key 不是从 0 开始的
echo "array_is_list([1 => 'apple', 'orange']):";
dump(array_is_list([1 => 'apple', 'orange']));

// Key 都是数字,但不是按照顺序的
echo "array_is_list([1 => 'apple', 0 => 'orange']):";
dump(array_is_list([1 => 'apple', 0 => 'orange']));

// Key 非数字的
echo "array_is_list([0 => 'apple', 'foo' => 'bar']):";
dump(array_is_list([0 => 'apple', 'foo' => 'bar']));

// 不是按照顺序的
echo "array_is_list([0 => 'apple', 2 => 'bar']):";
dump(array_is_list([0 => 'apple', 2 => 'bar']));

使用 PHP 代码实现 array_is_list() 函数:

function array_is_list(array $array): bool {
    if (empty($array)) {
        return true;
    }

    $current_key = 0;
    foreach ($array as $key => $noop) {
        if ($key !== $current_key) {
            return false;
        }
        ++$current_key;
    }

    return true;
}

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L03 构架 API 服务器》
你将学到如 RESTFul 设计风格、PostMan 的使用、OAuth 流程,JWT 概念及使用 和 API 开发相关的进阶知识。
《G01 Go 实战入门》
从零开始带你一步步开发一个 Go 博客项目,让你在最短的时间内学会使用 Go 进行编码。项目结构很大程度上参考了 Laravel。
讨论数量: 0
发起讨论 查看所有版本


暂无话题~