- What is spatie/php-structure-discoverer used for?
- It is a PHP discovery utility that finds classes, interfaces, enums, and traits matching conditions such as implementing an interface, extending a parent, using an attribute, or satisfying a custom closure. It returns fully qualified class names and includes built-in caching so scans stay fast in production. Typical uses include handler registries, package service provider registration, and replacing hardcoded class lists.
- How do I install spatie/php-structure-discoverer in Laravel?
- Install it with composer require spatie/php-structure-discoverer. In Laravel, publish the package config through Laravel's vendor:publish flow if you need to customize discovery or cache settings. The optional Artisan commands structure-scouts:cache and structure-scouts:clear handle cache warming and clearing; no required application service needs to be registered.
- Does spatie/php-structure-discoverer work outside Laravel?
- Yes. The core package is framework-agnostic PHP and can be used in any Composer project. Laravel support is a thin optional veneer: config publishing, the structure-scouts:cache and structure-scouts:clear Artisan commands, and a LaravelDiscoverCacheDriver. You can call Discover directly without bootstrapping Laravel.
- How does caching work, and do I need to warm the cache after every deploy?
- The package caches discovery results so production is fast, but correctness depends on clearing or warming that cache at the right point in your deploy pipeline. A stale cache after a class rename can silently omit handlers instead of failing loudly. Use the Laravel structure-scouts:cache and structure-scouts:clear commands, or your own DiscoverCacheDriver implementation, as part of deploys and verify whether automatic invalidation is sufficient for your workflow.
- Is discovery static, or does it autoload classes to check interfaces and attributes?
- This is a key thing to verify for your codebase: confirm whether discovery is purely static (tokenizer or AST based) or whether it autoloads classes to evaluate attributes and interfaces. If you have classes that are not safe to autoload in every context, test those cases before relying on discovery. The package provides structure metadata, but the failure mode for unloadable or unparsable files should be validated in a staging environment.
- Does it support enums, PHP 8.1, and Laravel 10, 11, or 12?
- The package explicitly discovers classes, interfaces, enums, and traits, so enum-driven config surfaces are supported. The exact PHP and Laravel version matrix, including Laravel 10/11/12 and semver guarantees, should be checked against the package's composer constraints and release notes before adoption. Because the core is framework-agnostic, plain PHP projects have fewer constraints than Laravel apps.
- How do I discover classes with a specific attribute?
- Use the withAttribute filter on a Discover query, for example Discover::in(__DIR__)->classes()->withAttribute(YourAttribute::class)->get(). This lets implementations declare their own registration intent with an attribute instead of being listed in a central array. It is one of the highest-leverage features for reducing forgot-to-register bugs.
- Can I filter by interface, parent class, enum, trait, or a custom closure?
- Discovery conditions include structure type, interface implementation, parent class, attribute usage, and custom closures. Chain resolution across the extends and implements graph is explicitly resource-heavy, so it is best used at cache-warm time rather than per request. Combine filters carefully and benchmark cold scans against your largest directories.
- How fast is it at 5,000 to 20,000 files, and should I enable parallel scanning?
- Caching is the main performance mechanism; with a warm cache the package is designed to be fast in production. Parallel scanning is optional and requires amphp/parallel, so it only matters for cold scans. Benchmark your own 5k to 20k file tree, including memory for full() with chains enabled, because the inheritance chain resolution is described as resource-heavy.
- What are alternatives, and should I replace hardcoded class lists with this package?
- Alternatives include hand-rolled File::allFiles plus class_exists scanning, hardcoded class registries, or framework-specific discovery mechanisms. This package is best treated as a build and scan-time primitive and wrapped behind your own registry interface so domain code does not depend directly on Spatie\StructureDiscoverer. It is MIT licensed with a small public API, so forking or vendoring a patch is a viable escape hatch; note that the ecosystem is thin, so validate maintenance activity before standardizing on it.