Spread Operator (...)
debt(d7/e3/b3/t5)
Closest to 'only careful code review or runtime testing' (d7). The tools listed (rector, phpcs) can detect legacy patterns like call_user_func_array() and flag missing spread usage, but the critical version-mismatch bug — spreading associative arrays in PHP < 8.1 — is a runtime fatal error that only surfaces when that code path is exercised. Static analysis may not catch version-conditional misuse without explicit PHP version configuration, pushing this toward d7.
Closest to 'simple parameterised fix' (e3). The quick_fix describes replacing call_user_func_array() or array_merge() with spread syntax — a pattern-level swap that rector can automate, but common_mistakes include version-specific incompatibilities and semantic differences (re-indexing vs. override semantics) that require checking a few call sites. Slightly more than a one-liner but contained within individual call sites.
Closest to 'localised tax' (b3). The spread operator applies across web, cli, and queue-worker contexts in PHP 5.6+, but misuse is localised to individual function call sites or array expressions. The version constraint (PHP 8.1 for string keys) is a persistent but narrow tax — it doesn't reshape architecture, just requires awareness at specific usage points.
Closest to 'notable trap' (t5). The misconception field directly identifies the trap: developers assume spread works with all arrays, but string-keyed (associative) array spread only works in PHP 8.1+, throwing a fatal error on earlier versions. This is a documented gotcha that most PHP developers eventually learn but is non-obvious from the syntax alone. The semantic difference from array_merge() is a secondary gotcha.
Also Known As
TL;DR
Explanation
PHP's spread operator (...) serves two purposes: in function signatures it collects remaining arguments into an array (variadic), and in call sites or array literals it unpacks an iterable into individual elements. Since PHP 8.1, string-keyed arrays can be spread in function calls (named arguments). This enables array merging ($merged = [...$a, ...$b]) as a readable alternative to array_merge(), and passing stored argument lists to functions.
Common Misconception
Why It Matters
Common Mistakes
- Spreading a non-array or non-Traversable — causes a TypeError at runtime.
- Using spread for array merging when array_merge() semantics (re-indexing numerics, last-write-wins for strings) are needed.
- Spreading associative arrays in PHP 7 — string key spread was only added in PHP 8.1.
- Not knowing spread works in array literals: $merged = [...$defaults, ...$overrides].
Code Examples
// Old verbose approach:
$args = [1, 2, 3];
call_user_func_array('array_merge', $arrays); // Replaced by spread
// With spread operator:
function sum(int ...$nums): int { return array_sum($nums); }
$numbers = [1, 2, 3];
echo sum(...$numbers); // Clean argument unpacking
// Spread in function calls
function add(int $a, int $b, int $c): int { return $a + $b + $c; }
$args = [1, 2, 3];
echo add(...$args); // 6
// Spread in array literals
$first = [1, 2, 3];
$second = [4, 5, 6];
$merged = [...$first, ...$second]; // [1,2,3,4,5,6]
// PHP 8.1 — spread with string keys (named arguments style)
$defaults = ['color' => 'blue', 'size' => 'M'];
$options = ['size' => 'XL', ...$defaults]; // ['size' => 'M', 'color' => 'blue']
// Note: later keys win — order matters
// Variadic parameters
function sum(int ...$nums): int { return array_sum($nums); }
sum(1, 2, 3); // 6