← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Dead Code Detection

Code Quality PHP 7.1+ Intermediate
debt(d5/e3/b3/t5)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). Dead code is detected by specialist static analysis tools like PHPStan, Psalm, and Rector as listed in detection_hints.tools. IDEs catch some cases but miss dynamic dispatch and reflection-based calls. These are not default linters but dedicated analysis tools requiring configuration at higher levels.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix indicates running PHPStan level 6+ with dead code extension, and Rector can auto-remove many flagged items. However, common_mistakes notes the need to verify reflection/dynamic calls before deletion, making it slightly more than a one-line patch but still a localized fix within specific files.

b3 Burden Structural debt — long-term weight of choosing wrong

Closest to 'localised tax' (b3). Dead code detection is a tooling choice that applies across web/cli/queue-worker contexts per applies_to, but it's a quality practice that doesn't fundamentally shape the codebase architecture. Not running detection accumulates technical debt locally in affected components but doesn't impose system-wide structural constraints.

t5 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'notable trap' (t5). The misconception explicitly states that developers wrongly believe IDE warnings are sufficient to catch all dead code, when in fact IDEs miss code behind dynamic dispatch, reflection, and configuration-based exclusions. This is a documented gotcha that most developers eventually learn through experience with large codebases.

About DEBT scoring →

Also Known As

unreachable code detection dead code analysis unused code finder

TL;DR

Identifying code that can never be executed — unreachable branches, always-true conditions, unused variables — via static analysis or coverage reports.

Explanation

Dead code accumulates over time: unreachable branches after a return or throw, conditions that are always true or false due to type constraints, methods never called from anywhere, and variables written but never read. It increases cognitive load (readers wonder why it exists), masks real logic, and can hide bugs (the 'dead' branch may have been reached and mattered at some point). Detection tools: PHPStan level 4+ reports always-true/false conditions and unreachable code; Psalm's dead-code analysis finds uncalled methods with --find-dead-code; code coverage reports (Xdebug + PHPUnit) highlight never-executed lines. Remove dead code promptly — git history preserves it if needed. Never comment it out: commented code is worse than deleted code.

Common Misconception

IDE warnings are sufficient to catch all dead code. IDEs miss dead code behind dynamic dispatch, unreferenced public methods called via reflection, and code that is conditionally excluded by configuration rather than control flow.

Why It Matters

Automated dead code detection surfaces unreachable code that human review misses — eliminating it reduces attack surface, build times, and the cognitive cost of navigating the codebase.

Common Mistakes

  • Relying solely on manual code review to find dead code in large codebases — it scales poorly.
  • Not running PHPStan or Psalm at maximum level — lower levels skip unused method and property checks.
  • Deleting flagged dead code without checking if it's used via Reflection or dynamic calls like call_user_func.
  • Treating dead code warnings as low priority — they often indicate structural problems worth investigating.

Code Examples

✗ Vulnerable
class UserService {
    public function getUser(int $id): User { /* used */ }
    public function legacyFetch(int $id): User { /* never called — dead */ }
    private function internalHelper(): void { /* unreferenced — dead */ }
}
✓ Fixed
// PHP tools that find dead code:

// PHPStan — flags unreachable code and unused methods:
$ vendor/bin/phpstan analyse --level=6 src/
// 'Call to an always-true condition'
// 'Return type is never used'

// Psalm — taint analysis also finds dead paths:
$ vendor/bin/psalm --find-dead-code

// php-dead-code-detector:
$ composer require --dev povils/phpmnd

// IDE support:
// PhpStorm highlights unreachable code, unused private methods in grey

// Git approach — blame + coverage:
// Lines never covered by tests AND never changed in 12 months = candidates
$ vendor/bin/phpunit --coverage-text | grep -v ' 100%'

// Remove dead code — don't comment it out; version control preserves history

Added 15 Mar 2026
Edited 22 Mar 2026
Views 55
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
1 ping T 1 ping W 1 ping T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 0 pings F 0 pings S 3 pings S 0 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 1 ping T 1 ping W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 2 pings T 0 pings W
No pings yet today
PetalBot 2
Amazonbot 10 Perplexity 7 Google 5 Scrapy 5 Ahrefs 4 Unknown AI 2 Claude 2 Bing 2 PetalBot 2 Majestic 1 ChatGPT 1 Meta AI 1 SEMrush 1
crawler 39 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Low
⚡ Quick Fix
Run PHPStan level 6+ with the dead code extension — it finds unused methods, unreachable code, and always-false conditions; Rector can auto-remove many of them
📦 Applies To
PHP 7.1+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
Private methods never called; code after return/throw; class never instantiated; constant never referenced
Auto-detectable: ✓ Yes phpstan psalm rector phploc
⚠ Related Problems
🤖 AI Agent
Confidence: High False Positives: Medium ✓ Auto-fixable Fix: Low Context: File Tests: Update
CWE-561


✓ schema.org compliant