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

Classy Laravel Package

ergebnis/classy

ergebnis/classy adds convenient helpers for working with PHP classes and reflection. Generate class names, namespaces, and short names, and inspect class metadata in a clean, test-friendly way—useful for tooling, libraries, and code generation.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require ergebnis/classy
    

    Add to composer.json if not auto-discovered:

    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "Ergebnis\\Classy\\": "vendor/ergebnis/classy/src/"
        }
    }
    

    Run composer dump-autoload.

  2. First Use Case: List all classes in a namespace (e.g., App\Models):

    use Ergebnis\Classy\Classy;
    
    $classes = Classy::classes('App\Models');
    foreach ($classes as $class) {
        echo $class->getName() . "\n";
    }
    
  3. Key Classes:

    • Classy: Main facade for collectors.
    • ClassCollector: Core collector for classes/enums/interfaces/traits.
    • ClassReflection: Reflection wrapper with caching.

Implementation Patterns

Common Workflows

  1. Namespace Scanning:

    // Get all classes in a namespace (recursive)
    $collector = new \Ergebnis\Classy\ClassCollector('App\\');
    $classes = $collector->getClasses();
    
    // Filter by trait
    $traitClasses = $collector->getClassesWithTrait(\Illuminate\Foundation\Testing\Concerns\InteractsWithContainer::class);
    
  2. Reflection with Caching:

    $reflection = Classy::reflect('App\Models\User');
    $methods = $reflection->getMethods();
    $properties = $reflection->getProperties();
    
  3. Integration with Laravel:

    • Service Providers:
      public function boot()
      {
          $this->app->singleton(Classy::class, function ($app) {
              return new Classy(new ClassCollector('App\\'));
          });
      }
      
    • Dynamic Registration: Use Classy to auto-register classes (e.g., for event listeners):
      $listeners = Classy::classes('App\\Events\\Handlers')
          ->filter(fn ($class) => $class->isSubclassOf(\Illuminate\Contracts\Queue\ShouldQueue::class))
          ->map(fn ($class) => [$class->getName(), 'handle']);
      
  4. Custom Collectors: Extend ClassCollector to add filters:

    class CustomCollector extends ClassCollector
    {
        public function getClassesWithAnnotation(string $annotation)
        {
            return $this->getClasses()
                ->filter(fn ($class) => $class->hasAnnotation($annotation));
        }
    }
    

Gotchas and Tips

Pitfalls

  1. Caching:

    • ClassReflection caches results by default. Clear cache manually if classes change:
      Classy::clearCache();
      
    • Disable caching in constructor:
      new ClassCollector('App\\', cache: false);
      
  2. Performance:

    • Avoid scanning large namespaces repeatedly. Cache results in a service container or Redis:
      $this->app->singleton('app.classes', function () {
          return cache()->remember('app.classes', now()->addHours(1), fn () =>
              Classy::classes('App\\')->all()
          );
      });
      
  3. Edge Cases:

    • Anonymous Classes: Not supported (expected behavior).
    • Dynamic Proxies: May cause reflection errors. Use isProxy() check:
      if (!$reflection->isProxy()) {
          // Safe to inspect
      }
      
  4. Laravel-Specific:

    • Facades: Use Classy::reflect(FooFacade::class)->getOriginalClass() to resolve facades.
    • Service Bindings: Classes bound via bind() may not appear in scans. Use app()->bound() to verify.

Tips

  1. Combining Collectors:

    $collector = new ClassCollector('App\\');
    $models = $collector->getClasses()
        ->filter(fn ($class) => $class->isSubclassOf(\Illuminate\Database\Eloquent\Model::class));
    
  2. Annotation Support: Use with packages like doctrine/annotations for metadata:

    $annotatedClasses = $collector->getClasses()
        ->filter(fn ($class) => $class->hasAnnotation('\\Some\\Annotation'));
    
  3. Testing: Mock Classy in tests:

    $this->mock(Classy::class)->shouldReceive('classes')
        ->andReturn(collect([new ClassReflection('Mock\\Class')]));
    
  4. Extension Points:

    • Override ClassReflection to add custom methods (e.g., hasMethodWithAttribute).
    • Extend ClassCollector to support custom file patterns (e.g., *.test.php).
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport
twbs/bootstrap4