PHP数组声明中的扩展语法

50

PHP支持可变参数函数的展开语法。

在JavaScript中,您可以使用展开语法来实现这个

var a = [1, 2];
var b = [...a, 3, 4];
console.log(b); // [1, 2, 3, 4]

然而,尝试在PHP中实现这个目标:

$a = [1, 2];
$b = [...$a, 3, 4];
var_dump($b);die;

这个错误的原因是:

解析错误:语法错误,意外的 '...'(T_ELLIPSIS),期望 ']'

在 PHP 中不允许使用这种扩展语法吗?如果不行,有没有同样优雅的方法来实现相同的效果?


10
不,PHP没有神奇的快捷语法:只有基本的$b = array_merge($a, [3, 4]); - Mark Baker
4
自2019年12月起,这是PHP的一部分。http://wiki.php.net/rfc/spread_operator_for_array - Tomas Votruba
1
这是自2019年或2018年12月起成为PHP的一部分吗?我评论的当前日期是2019年5月13日。 - chalo
3
它将在PHP 7.4中可用。 - CedX
4个回答

66

在 PHP 7.4 中实现了数组RFC中的扩展运算符:

$ary = [3, 4, 5];
return [1, 2, ...$ary]; // same as [1, 2, 3, 4, 5]

注意:未打包的数组/可遍历对象只能具有整数键。对于字符串键,仍需使用array_merge()


1
现在,在 PHP 8.1+ 中,展开运算符支持具有字符串键的数组。请参阅 https://wiki.php.net/rfc/array_unpacking_string_keys。 - Drew
现在,在 PHP ^8.1 中不再使用 array_merge() 函数来处理字符串。 - undefined

18

更新:数组表达式中的扩展运算符

来源https://wiki.php.net/rfc/spread_operator_for_array

Version: 0.2
Date: 2018-10-13
Author: CHU Zhaowei, jhdxr@php.net
Status: Implemented (in PHP 7.4)
在数组定义过程中,前缀为的数组对将被展开。只有实现了Traversable接口的数组和对象才能够被展开。

例如:

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

可以多次使用扩展运算符,而且与参数解包不同,它可以在任何地方使用。在扩展运算符之前或之后添加正常元素是可行的。

扩展运算符适用于数组语法(array())和短语法([])。

还可以立即解包函数返回的数组。

$arr1 = [1, 2, 3];
$arr2 = [...$arr1]; //[1, 2, 3]
$arr3 = [0, ...$arr1]; //[0, 1, 2, 3]
$arr4 = array(...$arr1, ...$arr2, 111); //[1, 2, 3, 1, 2, 3, 111]
$arr5 = [...$arr1, ...$arr1]; //[1, 2, 3, 1, 2, 3]

function getArr() {
  return ['a', 'b'];
}
$arr6 = [...getArr(), 'c']; //['a', 'b', 'c']

$arr7 = [...new ArrayIterator(['a', 'b', 'c'])]; //['a', 'b', 'c']

function arrGen() {
    for($i = 11; $i < 15; $i++) {
        yield $i;
    }
}
$arr8 = [...arrGen()]; //[11, 12, 13, 14]

<---------------更新结束-------------------->

首先,你在错误地引用具有数组的可变参数函数。

你可以创建自己的方法来完成这个任务,或者像 @Mark Baker 在你的问题下的评论中建议的那样更好地使用 array_merge

如果你仍然想要使用展开运算符 / ...,你可以自己实现类似于以下代码:

<?php
function merge($a, ...$b) {
    return array_merge($a,$b);
}

$a = [1, 2];
$b = [3,4];
print_r( merge($a, ...$b));
?>

但在我看来,这样做是愚蠢的。因为你仍然需要使用像array_merge这样的东西。即使一种语言实现了这个功能,在幕后该语言也会使用merge函数,其中包含将两个数组的所有元素复制到单个数组中的代码。

我写下这个答案只是因为你要求一种做法,并且优雅是你的要求。

更合理的例子:

<?php
$a = [1,2,3,56,564];
$result = merge($a, 332, 232, 5434, 65);
var_dump($result);
?>

如果我想保留键,怎么办?在这种情况下,array_merge是不够的。 - Facedown
@Facedownn,你试过这段代码了吗?array_merge会保留键。或者你指的是其他什么? - Ravinder Payal
以下示例不会保留键,导致输出了4个项目,但我只想要2个。 array_merge(...[[2 => 'foo', 3 => 'bar'], [2 => 'foo', 3 => 'baz']]) 我正在寻找类似于+(加号)运算符的东西来处理这种情况。 - Facedown
@Facedown请问另一个问题,这与您所询问的内容无关。 - Ravinder Payal

7

PHP 7.4以下版本

$mainArray = ['element1', 'element2'];
$finalArray = array_merge($mainArray, ['element3']);
print_r($finalArray);
// Final array would be ['element1', 'element2', 'element3'];

在 PHP 7.4 及以上版本中

$mainArray = ['element1', 'element2'];
$finalArray = [...$mainArray, 'element3'];
print_r($finalArray);
// Final array would be ['element1', 'element2', 'element3'];

6

在PHP 7.4中,您现在可以在数组表达式中使用扩展运算符。

$parts = ['apple', 'pear'];
$fruits = ['banana', 'orange', ...$parts, 'watermelon'];
// ['banana', 'orange', 'apple', 'pear', 'watermelon'];

2
非常好!你的信息来源是什么? - Nathan Arthur
3
找到提案了,看起来这个还不是现成的功能,但很可能会在7.4版本中实现:https://wiki.php.net/rfc/spread_operator_for_array - Nathan Arthur

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接