Unused Variable
debt(d5/e1/b3/t7)
Closest to 'specialist tool catches it' (d5). The detection_hints list phpstan, psalm, and phpcs — all specialist static-analysis tools that must be deliberately configured (e.g. phpstan level 4+). No PHP compiler or default linter catches this automatically; it requires intentional tooling setup.
Closest to 'one-line patch or single-call swap' (e1). The quick_fix states: enable phpstan level 4+ and phpcs. Once detected, the fix is either deleting the unused variable, correcting a typo in the variable name, or adding a log call — all single-line or trivial changes.
Closest to 'localised tax' (b3). The issue is scoped to individual variables within functions or methods. It applies broadly across web, cli, and queue-worker contexts, but each instance is self-contained; it does not impose a cross-cutting architectural weight on the codebase.
Closest to 'serious trap — contradicts how a similar concept works elsewhere' (t7). The misconception field explicitly states that developers treat unused variables as mere style issues, when in reality an unused variable after a function call silently discards a return value that may be an error indicator. This contradicts the intuition that 'the function was called, so its effect happened' — the result (e.g. error signal) is silently lost, causing undetected failures. This is a deeper trap than a documented gotcha.
Also Known As
TL;DR
Explanation
Unused variables come in two flavours: assigned and never read (possible logic error — was the value supposed to be used?), and loop variables assigned inside a loop but overwritten before being read (result discarded). PHP lacks compile-time unused variable warnings unlike strongly typed languages. PHPStan level 5+ and Psalm detect them. The fix is either to use the variable or to remove the assignment. In foreach, prefix unused variables with underscore by convention: foreach ($items as $_key => $value).
Common Misconception
Why It Matters
Common Mistakes
- Assigning a function's return value to a variable then never using it — the return value likely matters.
- Reassigning a variable in a loop before reading the previous value — the first assignment was wasted.
- Unused catch variable: catch (Exception $e) {} — at least log $e.
- Unnecessary intermediate variables that just hold a value passed directly to the next call.
Code Examples
// Return value assigned but ignored:
$result = $pdo->exec($sql); // 0 means 0 rows affected — never checked
$userId = getUserId(); // Assigned
$user = findUser(); // $userId never used — logic error?
return $user;
// Overwritten before read:
foreach ($items as $item) {
$total = 0; // Reset every iteration — previous value lost
$total += $item->price;
}
// Check return values:
$affected = $pdo->exec($sql);
if ($affected === 0) throw new RuntimeException('No rows updated');
// Use what you assign:
$userId = getUserId();
$user = findUser($userId); // $userId used
return $user;
// Fix loop — move init outside:
$total = 0;
foreach ($items as $item) {
$total += $item->price;
}