Spread Operator in Arrays [...$a, ...$b]
debt(d5/e1/b1/t5)
Closest to 'specialist tool catches' (d5), Rector can detect and transform array_merge() to spread syntax, but the key-reindexing surprise is silent until tests catch it.
Closest to 'one-line patch or single-call swap' (e1), quick_fix is a direct replacement of array_merge($a, $b) with [...$a, ...$b].
Closest to 'minimal commitment' (b1), this is a localised syntactic choice per array literal with no architectural reach.
Closest to 'notable trap most devs eventually learn' (t5), misconception states integer keys are re-indexed (not preserved) — a documented gotcha matching array_merge semantics that surprises devs expecting key preservation.
TL;DR
Explanation
PHP 7.4 added spread in function calls. PHP 8.1 added spread in array expressions: [...$a, ...$b] creates a new merged array. Key behavior: integer keys are re-indexed (like array_merge), string keys from later arrays overwrite earlier ones (like array_merge). PHP 8.1 also allows string-keyed spreads. Spread preserves no reference — it creates copies. For associative merging with last-write-wins semantics, [...$defaults, ...$overrides] is idiomatic.
Common Misconception
Why It Matters
Common Mistakes
- Expecting integer keys to be preserved — they're re-indexed.
- Using spread with string keys before PHP 8.1 — fatal error in PHP 7.4 spread.
- Not knowing that [...$a, ...$b] and array_merge($a, $b) behave identically for simple cases.
Code Examples
$merged = array_merge($defaults, $userConfig, ['debug' => false]);
// Works but verbose
// PHP 8.1+ idiomatic:
$config = [...$defaults, ...$userConfig, 'debug' => false];
// Cloning with overrides:
$updated = [...$original, 'status' => 'active', 'updated_at' => now()];
// Conditional spread:
$params = [
'limit' => 20,
...($search ? ['q' => $search] : []),
];