可變長度引數列表

Version >= 5.6

PHP 5.6 引入可變長度引數列表(也稱為可變引數,可變引數),使用引數名稱前的 ... 令牌以指示該引數是可變引數,即,它是包括來自一個起的所有提供的引數的陣列。

function variadic_func($nonVariadic, ...$variadic) {
    echo json_encode($variadic);
}

variadic_func(1, 2, 3, 4); // prints [2,3,4]

型別名稱可以新增到 ... 前面:

function foo(Bar ...$bars) {}

& 引用運算子可以在 ... 之前新增,但在型別名稱之後(如果有的話)新增。考慮這個例子:

class Foo{}
function a(Foo &...$foos){
    $i = 0;
    foreach($a as &$foo){ // note the &
        $foo = $i++;
    }
}
$a = new Foo;
$c = new Foo;
$b =& $c;
a($a, $b);
var_dump($a, $b, $c);

輸出:

int(0)
int(1)
int(1)

另一方面,引數陣列(或 Traversable)可以解壓縮,以引數列表的形式傳遞給函式:

var_dump(...hash_algos());

輸出:

string(3) "md2"
string(3) "md4"
string(3) "md5"
...

與此片段比較而不使用 ...

var_dump(hash_algos());

輸出:

array(46) {
  [0]=>
  string(3) "md2"
  [1]=>
  string(3) "md4"
  ...
}

因此,現在可以輕鬆地進行可變引數函式的重定向功能,例如:

public function formatQuery($query, ...$args){
    return sprintf($query, ...array_map([$mysqli, "real_escape_string"], $args));
}

除了陣列之外,還可以使用 Traversables,例如 Iterator(尤其是來自 SPL 的許多子類)。例如:

$iterator = new LimitIterator(new ArrayIterator([0, 1, 2, 3, 4, 5, 6]), 2, 3);
echo bin2hex(pack("c*", ...$it)); // Output: 020304

如果迭代器無限迭代,例如:

$iterator = new InfiniteIterator(new ArrayIterator([0, 1, 2, 3, 4]));
var_dump(...$iterator);

不同版本的 PHP 表現不同:

  • 從 PHP 7.0.0 到 PHP 7.1.0(beta 1):
    • 將發生分段錯誤
    • PHP 程序將以程式碼 139 退出
  • 在 PHP 5.6 中:
    • 將顯示記憶體耗盡的致命錯誤(“允許的記憶體大小為%d 位元組耗盡”)。
    • PHP 程序將以程式碼 255 退出

注意:HHVM(v3.10 - v3.12)不支援解包 Traversables。此嘗試中將顯示警告訊息僅解包容器