dead-code-detector
dead-code-detector copied to clipboard
PHP unused code detection via PHPStan extension.
trafficstars
Dead code detector for PHP
PHPStan extension to find unused PHP code in your project with ease!
Installation:
composer require --dev shipmonk/dead-code-detector
Use official extension-installer or just load the rules:
includes:
- vendor/shipmonk/dead-code-detector/rules.neon
Supported libraries
- Any overridden method that originates in
vendoris not reported as dead - We also support many magic calls in following libraries:
Symfony:
- constructor calls for DIC services!
phpstan/phpstan-symfonywithcontainerXmlPathmust be used
#[AsEventListener]attribute#[AsController]attribute#[AsCommand]attribute#[Required]attribute#[Route]attributesonKernelResponse,onKernelRequest, etc
Doctrine:
#[AsEntityListener]attributeDoctrine\ORM\Events::*eventsDoctrine\Common\EventSubscribermethods- lifecycle event attributes
#[PreFlush],#[PostLoad], ...
PHPUnit:
- data provider methods
testXxxmethods- annotations like
@test,@before,@afterClassetc - attributes like
#[Test],#[Before],#[AfterClass]etc
PHPStan:
- constructor calls for DIC services (rules, extensions, ...)
Nette:
handleXxx,renderXxx,actionXxx,injectXxx,createComponentXxxSmartObjectmagic calls for@propertyannotations
All those libraries are autoenabled when found within your composer dependencies. If you want to force enable/disable some of them, you can:
# phpstan.neon.dist
parameters:
shipmonkDeadCode:
entrypoints:
phpunit:
enabled: true
Customization:
- If your application does some magic calls unknown to this library, you can implement your own entrypoint provider.
- Just tag it with
shipmonk.deadCode.entrypointProviderand implementShipMonk\PHPStan\DeadCode\Provider\MethodEntrypointProvider - You can simplify your implementation by extending
ShipMonk\PHPStan\DeadCode\Provider\MethodBasedEntrypointProvider
# phpstan.neon.dist
services:
-
class: App\ApiOutputEntrypointProvider
tags:
- shipmonk.deadCode.entrypointProvider
use ReflectionMethod;
use ShipMonk\PHPStan\DeadCode\Provider\SimpleMethodEntrypointProvider;
class ApiOutputEntrypointProvider extends SimpleMethodEntrypointProvider
{
public function isEntrypointMethod(ReflectionMethod $method): bool
{
return $method->getDeclaringClass()->implementsInterface(ApiOutput::class));
}
}
Comparison with tomasvotruba/unused-public
- You can see detailed comparison PR
- Basically, their analysis is less precise and less flexible. Mainly:
- It cannot detect dead constructors
- It does not properly detect calls within inheritance hierarchy
- It does not offer any custom adjustments of used methods
- It has almost no built-it library extensions
- It ignores trait methods
- Is lacks many minor features like class-string calls, dynamic method calls, array callbacks, nullsafe call chains etc
Limitations:
- Only method calls are detected so far
- Including constructors, static methods, trait methods, interface methods, first class callables, clone, etc.
- Any calls on mixed types are not detected, e.g.
$unknownClass->method() - Anonymous classes are ignored (PHPStan limitation)
- Does not check most magic methods (
__get,__setetc) - Call-graph not implemented so far
- No transitive check is performed (dead method called only from dead method)
- No dead cycles are detected (e.g. dead method calling itself)
Contributing
- Check your code by
composer check - Autofix coding-style by
composer fix:cs - All functionality must be tested
Supported PHP versions
- PHP 7.4 - 8.3