002. PHP 8.1 更新之数组:解包数组和 array_is_list 函数
说明
大家好,这个视频我来演示下 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;
}