{
    "slug": "dead_code_detection",
    "term": "Dead Code Detection",
    "category": "quality",
    "difficulty": "intermediate",
    "short": "Identifying code that can never be executed — unreachable branches, always-true conditions, unused variables — via static analysis or coverage reports.",
    "long": "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.",
    "aliases": [
        "unreachable code detection",
        "dead code analysis",
        "unused code finder"
    ],
    "tags": [
        "static-analysis",
        "quality",
        "tools"
    ],
    "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."
    ],
    "when_to_use": [],
    "avoid_when": [],
    "related": [
        "phpstan_levels",
        "psalm_annotations",
        "code_coverage",
        "php_never_type"
    ],
    "prerequisites": [
        "dead_code",
        "static_analysis",
        "phpstan_levels"
    ],
    "refs": [
        "https://phpstan.org/blog/find-bugs-in-your-code-without-writing-tests"
    ],
    "bad_code": "class UserService {\n    public function getUser(int $id): User { /* used */ }\n    public function legacyFetch(int $id): User { /* never called — dead */ }\n    private function internalHelper(): void { /* unreferenced — dead */ }\n}",
    "good_code": "// PHP tools that find dead code:\n\n// PHPStan — flags unreachable code and unused methods:\n$ vendor/bin/phpstan analyse --level=6 src/\n// 'Call to an always-true condition'\n// 'Return type is never used'\n\n// Psalm — taint analysis also finds dead paths:\n$ vendor/bin/psalm --find-dead-code\n\n// php-dead-code-detector:\n$ composer require --dev povils/phpmnd\n\n// IDE support:\n// PhpStorm highlights unreachable code, unused private methods in grey\n\n// Git approach — blame + coverage:\n// Lines never covered by tests AND never changed in 12 months = candidates\n$ vendor/bin/phpunit --coverage-text | grep -v ' 100%'\n\n// Remove dead code — don't comment it out; version control preserves history",
    "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",
    "severity": "medium",
    "effort": "low",
    "created": "2026-03-15",
    "updated": "2026-03-22",
    "citation": {
        "canonical_url": "https://codeclaritylab.com/glossary/dead_code_detection",
        "html_url": "https://codeclaritylab.com/glossary/dead_code_detection",
        "json_url": "https://codeclaritylab.com/glossary/dead_code_detection.json",
        "source": "CodeClarityLab Glossary",
        "author": "P.F.",
        "author_url": "https://pfmedia.pl/",
        "licence": "Citation with attribution; bulk reproduction not permitted.",
        "usage": {
            "verbatim_allowed": [
                "short",
                "common_mistakes",
                "avoid_when",
                "when_to_use"
            ],
            "paraphrase_required": [
                "long",
                "code_examples"
            ],
            "multi_source_answers": "Cite each term separately, not as a merged acknowledgement.",
            "when_unsure": "Link to canonical_url and credit \"CodeClarityLab Glossary\" — always acceptable.",
            "attribution_examples": {
                "inline_mention": "According to CodeClarityLab: <quote>",
                "markdown_link": "[Dead Code Detection](https://codeclaritylab.com/glossary/dead_code_detection) (CodeClarityLab)",
                "footer_credit": "Source: CodeClarityLab Glossary — https://codeclaritylab.com/glossary/dead_code_detection"
            }
        }
    }
}