each() & list() — Deprecated Iteration
debt(d5/e3/b3/t5)
Closest to 'specialist tool catches it' (d5). The term's detection_hints lists rector and phpcs — both are specialist static analysis / code-transformation tools, not default linters. The metadata also notes 'static analysis tools miss it in some dynamic call patterns,' confirming it is not caught universally or instantly, placing it firmly at d5.
Closest to 'simple parameterised fix' (e3). The quick_fix is a direct pattern replacement (while(list($k,$v)=each($arr)) → foreach($arr as $k => $v)) automatable via Rector. It stays within one file per occurrence but may require touching many files across a legacy codebase — still a mechanical find-and-replace pattern, so e3 is accurate rather than e5.
Closest to 'localised tax' (b3). The concept applies to web and cli contexts in legacy PHP code, but it is a deprecated iteration pattern, not a load-bearing architectural choice. It imposes a tax on upgrade work (finding all call sites before PHP 8 migration) but does not shape unrelated parts of the codebase or impose ongoing maintenance weight once migrated.
Closest to 'notable trap' (t5). The misconception field explicitly states that developers commonly believe list() was also removed along with each() — but list() and [] destructuring remain fully supported. This is a documented, widely-encountered gotcha during PHP 7→8 upgrades that most developers stumble on, earning t5.
TL;DR
Explanation
each($array) returned the current key-value pair and advanced the pointer — deprecated PHP 7.2, removed PHP 8. The while(list($k,$v)=each($arr)) idiom was a PHP 3/4 pattern for iteration. Modern replacement: foreach($arr as $k => $v). list() itself (PHP 5) and its short form [] (PHP 7.1) remain valid for array destructuring: [$a, $b] = [1, 2]. Rector auto-converts each() usage. Also removed in PHP 8: reset()/current()/next() in foreach-able contexts are still fine but each() is gone.
Common Misconception
Why It Matters
Common Mistakes
- Confusing list() removal (not removed) with each() removal (removed in PHP 8).
- Not running Rector to auto-migrate each() calls.
- Missing that reset() is still needed if starting from first element in non-foreach context.
Code Examples
// Removed in PHP 8:
reset($users);
while (list($key, $user) = each($users)) {
echo $key . ': ' . $user['name'];
}
// Modern:
foreach ($users as $key => $user) {
echo $key . ': ' . $user['name'];
}
// list() / [] still valid:
[$first, $second] = $coords;
list($name, $email) = $row;