Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Analyzer Laravel Package

graham-campbell/analyzer

Analyzer is a PHP tool by Graham Campbell that scans your code/tests to verify referenced classes actually exist, catching typos and broken imports early. Requires PHP 8.1–8.5 and supports PHPUnit 10–13 (v5.1).

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Install via Composer (dev dependency):
    composer require --dev graham-campbell/analyzer:^5.1
    
  2. Add to PHPUnit (create or update phpunit.xml):
    <phpunit>
        <extensions>
            <extension class="GrahamCampbell\Analyzer\Extension"/>
        </extensions>
    </phpunit>
    
  3. Run tests:
    ./vendor/bin/phpunit
    

First Use Case: Validate Class References

Create a test class extending GrahamCampbell\Analyzer\TestCase:

use GrahamCampbell\Analyzer\TestCase;

class ClassReferenceTest extends TestCase
{
    protected function getPaths(): array
    {
        return [__DIR__.'/../src'];
    }
}

Run the test to detect missing or invalid class references in your codebase.


Implementation Patterns

1. Integration with Laravel Projects

  • Service Providers: Validate register()/boot() methods for missing classes (e.g., App\Services\PaymentService).
    use GrahamCampbell\Analyzer\TestCase;
    
    class PaymentServiceProviderTest extends TestCase
    {
        protected function getPaths(): array
        {
            return [app_path('Providers')];
        }
    }
    
  • Facades: Ensure facade classes (e.g., App\Facades\PaymentFacade) reference valid underlying classes.
  • API Resources: Check toArray()/with() methods for model/relationship references.

2. PHPDoc Validation

Extend provideFilesToCheck() to include PHPDoc-heavy files (e.g., controllers, DTOs):

protected function provideFilesToCheck(): array
{
    return [
        __DIR__.'/../app/Http/Controllers',
        __DIR__.'/../app/Dtos',
    ];
}

3. CI/CD Workflow

Add to .github/workflows/ci.yml:

- name: Analyze Class References
  run: ./vendor/bin/phpunit --extension GrahamCampbell\Analyzer\Extension

Run before tests to fail fast on broken references.

4. Ignoring False Positives

Override getIgnored() to exclude known third-party or dynamic classes:

protected function getIgnored(): array
{
    return [
        'Illuminate\Support\Collection', // Dynamically extended
        'Laravel\Nova\Nova',           // Managed by Nova
    ];
}

5. Custom File Filtering

Use shouldAnalyzeFile() to skip specific files (e.g., generated stubs):

protected function shouldAnalyzeFile(string $file): bool
{
    return !Str::contains($file, 'generated/');
}

Gotchas and Tips

Pitfalls

  1. False Negatives with Dynamic Classes:

    • Classes loaded via class_alias() or eval() won’t be detected. Exclude these from analysis or mock them in tests.
    • Workaround: Use getIgnored() to whitelist dynamic classes.
  2. PHPDoc Parsing Quirks:

    • Complex PHPDoc (e.g., @template-extends) may cause parsing errors. Simplify annotations or update the package.
    • Debug Tip: Check phpunit.xml for @php tags to set error_reporting:
      <php>
          <ini name="error_reporting" value="-1"/>
      </php>
      
  3. Performance in Large Codebases:

    • Analysis can slow down CI. Optimize by:
      • Limiting getPaths() to critical directories (e.g., app/, src/).
      • Running in parallel with phpunit --parallel.
  4. Namespace Conflicts:

    • If your project uses use App; aliases, the package won’t resolve them. Stick to fully qualified names or mock the resolver.
  5. PHPUnit Version Mismatch:

    • Ensure your phpunit.xml matches the package’s supported versions (v5.1 requires PHPUnit 10–13).
    • Fix: Update Composer constraints or downgrade the package.

Debugging Tips

  • Verbose Output: Enable debug mode in phpunit.xml:
    <phpunit>
        <extensions>
            <extension class="GrahamCampbell\Analyzer\Extension" debug="true"/>
        </extensions>
    </phpunit>
    
  • Isolate Issues: Test individual files/directories by overriding getPaths().
  • Check Logs: Errors appear in the PHPUnit output or storage/logs/laravel.log.

Extension Points

  1. Custom Analyzers: Extend GrahamCampbell\Analyzer\Analyzer to add rules (e.g., validate interface implementations):

    class InterfaceAnalyzer extends Analyzer
    {
        public function analyze(Node $node): void
        {
            if ($node instanceof ClassLike) {
                $implements = $node->implements();
                foreach ($implements as $interface) {
                    if (!$this->classExists($interface->toString())) {
                        $this->fail($node, "Interface {$interface} does not exist.");
                    }
                }
            }
        }
    }
    
  2. Hook into Laravel Events: Trigger analysis on booted or registered events in AppServiceProvider:

    use GrahamCampbell\Analyzer\Analyzer;
    
    public function boot()
    {
        $analyzer = new Analyzer();
        $analyzer->analyzeFiles([app_path('Providers')]);
    }
    
  3. Artisan Command: Create a custom command for ad-hoc analysis:

    use GrahamCampbell\Analyzer\Analyzer;
    use Illuminate\Console\Command;
    
    class AnalyzeCommand extends Command
    {
        protected $signature = 'analyze:classes';
        protected $description = 'Analyze class references in the codebase';
    
        public function handle()
        {
            $analyzer = new Analyzer();
            $analyzer->analyzeFiles([base_path('app')]);
            $this->info('Analysis complete. See PHPUnit output for errors.');
        }
    }
    

Configuration Quirks

  • Case Sensitivity: The package respects filesystem case sensitivity. On case-insensitive filesystems (e.g., Windows), ensure class names match exactly.
  • Autoloading: Classes must be autoloadable (PSR-4 compliant). Exclude vendor/ or node_modules/ from getPaths().
  • Traits: The package handles traits, but nested trait references may require explicit whitelisting in getIgnored().
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
ecotone/kafka
22h/doctrine-garbage-collection-bundle
agtp/agtp-php
agtp/mod-php
splash/sonata-admin
splash/metadata