graham-campbell/analyzer
Analyzer is a PHP test utility by Graham Campbell that checks your code for references to classes that don’t actually exist. Compatible with PHP 8.1–8.5 and PHPUnit 10–13, helping catch broken imports and missing dependencies early.
AnalysisTrait) for extensibility, allowing customization of:
getPaths()).getIgnored()).shouldAnalyzeFile()).composer require --dev, with no runtime dependencies (dev-only).phpunit.xml configuration.| Risk Area | Mitigation Strategy |
|---|---|
| False Positives | Customizable getIgnored() to exclude known third-party classes (e.g., Laravel core). |
| Performance | Lightweight (uses PHP Parser v2), but benchmark in CI for large codebases (>50K LOC). |
| PHPUnit Version Lock | Pin to ^5.1 for PHP 8.5 support; avoid version conflicts with Laravel’s PHPUnit. |
| PHPDoc Parsing | May misinterpret complex PHPDoc (e.g., @template-extends). Test with real-world annotations. |
| Namespace Aliases | Does not resolve use App;—requires explicit FQCNs. Document this limitation. |
| Dynamic Loading | Fails on eval(), class_alias(), or runtime namespace changes. Exclude dynamic files. |
Illuminate\Support\Facades\Route)?composer.json?--dev, avoiding runtime overhead.phpunit --testdox-html.composer require --dev graham-campbell/analyzer:^5.1
AnalyzerTestCase:
use GrahamCampbell\Analyzer\AnalyzerTestCase;
class ClassReferenceTest extends AnalyzerTestCase
{
protected static function getPaths(): array
{
return [__DIR__ . '/../../app', __DIR__ . '/../../config'];
}
protected static function getIgnored(): array
{
return [
'Illuminate\\*', // Skip Laravel core
'Laravel\\SerializableClosure', // Dynamic classes
];
}
}
phpunit.xml:
<phpunit>
<extensions>
<extension class="GrahamCampbell\Analyzer\Extension"/>
</extensions>
</phpunit>
# GitHub Actions example
- name: Run Class Reference Analyzer
run: vendor/bin/phpunit --testdox-html --colors=never tests/ClassReferenceTest
app/Providers, app/Http/Controllers).| Component | Compatibility Notes |
|---|---|
| Laravel 10+ | Full support (PHP 8.5, modern PHPDoc). |
| PHPUnit 10–13 | Version ^5.1 supports all; pin to avoid conflicts. |
| PHP 8.1–8.5 | Native support; no polyfills needed. |
| Custom PHPDoc | May misparse complex annotations (e.g., @mixin). Test with real-world cases. |
| Dynamic Classes | Fails on: |
- `eval()` or `create_function()`.
- Runtime namespace aliases (e.g., `use App;`).
- Dynamic proxies (e.g., Eloquent’s `HasMany` relationships). |
| Third-Party SDKs | Whitelist SDK PHPDoc classes (e.g., Stripe\*) in getIgnored(). |
composer dump-autoload to ensure autoloader is up-to-date.bootstrap/cache/) from analysis.--testdox-html) for developer feedback.^5.1 for PHP 8.5 support; monitor for breaking changes.config/analyzer.php) for:
Illuminate\*).Stripe\*, PayPal\*).Laravel\SerializableClosure).getIgnored() for known safe classes.README.md or CONTRIBUTING.md.@property App\Post $post).composer dump-autoload).--verbose to see skipped files.--filter to test specific paths..analyzer.md file with:
How can I help you explore Laravel packages today?