hanneskod/classtools
Scan the filesystem for PHP classes, interfaces, and traits using Symfony Finder. Build a class-to-file map, detect parse/syntax errors, and iterate results as ReflectionClass objects, with optional autoloading for discovered classes.
Strengths:
ReflectionClass (runtime) with filesystem scanning (compile-time), enabling tools like:
Illuminate\Contracts\Auth\Authenticatable.new in App\Services").type(), inNamespace(), where()) mirror Laravel’s Eloquent/Collection methods, easing adoption.Gaps:
Container, ServiceProvider, or Facade system. Requires custom bridges (e.g., wrapping ClassIterator in a Laravel service).boot() or register() methods.nikic/PHP-Parser.Core Laravel Compatibility:
composer require hanneskod/classtools.files() helper and Illuminate\Filesystem.SplFileInfo and Traversable interfaces.AppServiceProvider).enableAutoloading() may interfere with Laravel’s ClassLoader if not isolated.php artisan scan:classes) rather than runtime logic.Key Integration Points:
| Laravel Feature | Integration Approach | Risk |
|---|---|---|
| Service Container | Bind ClassIterator as a singleton or context-bound service in AppServiceProvider. |
High (Reflection + Container) |
| Artisan Commands | Create custom commands (e.g., scan:classes, generate:api) using ClassIterator. |
Low |
| Facades/Macros | Wrap ClassIterator methods in a Facade for DSL-like syntax (e.g., ClassTools::scan()). |
Medium (Magic Method Overhead) |
| Event System | Trigger events (e.g., ClassesDiscovered) to notify other services of scan results. |
Low |
| Testing (PHPUnit) | Use in DataProvider or Extension traits to dynamically load test classes. |
Low |
Critical Risks:
enableAutoloading() triggers Laravel’s autoloader recursively, causing infinite loops or memory exhaustion.spl_autoload_register() temporarily.bootstrap/cache/ with a TTL (e.g., 1 hour).Illuminate\Support\Collection).\hanneskod\classtools\Filter\Type) and test against Laravel’s core.getErrors() returns raw PHP parse errors, which don’t integrate with Laravel’s exception system.ClassDiscoveryException).Medium Risks:
str_replace('\\', '/', $path)).bind(), tag(), or when() container methods.Low Risks:
getClassMap() vs. iterating with ReflectionClass?ClassIterator to Laravel’s IoC without autoloader conflicts?bind() or tag() methods for dynamic service registration?getErrors() with Laravel’s exception system (e.g., throw new ClassDiscoveryException($errors))?php-parser or roave/security-advisories?Laravel Ecosystem:
files() helper and Illuminate\Filesystem. Minimal friction.scan:classes, generate:api). Avoid runtime usage in boot().ReflectionClass usage (e.g., in app()->make() or new ReflectionClass()).Tooling Compatibility:
DataProvider traits or extensions to dynamically load test classes.Anti-Patterns:
boot() or register()—risk of slow boot times.enableAutoloading() can break Laravel’s ClassLoader. Prefer cached scans.nikic/PHP-Parser.| Phase | Action | Tools/Libraries | Risk |
|---|---|---|---|
| Evaluation | Benchmark scan times and memory usage on a staging clone of the codebase. | Blackfire, Laravel Debugbar | Low |
| Pilot | Build a proof-of-concept Artisan command (e.g., scan:unused-classes) to identify dead code. |
ClassIterator, FileCache |
Medium |
| Integration | Register ClassIterator as a Laravel service and create a Facade for DSL access. |
AppServiceProvider, Illuminate\Support\Facades |
High (Reflection) |
| Optimization | Cache scan results and run heavy operations asynchronously (e.g., Laravel Queues). | Illuminate\Cache, Illuminate\Queue |
Low |
| Extension | Add Laravel-specific filters (e.g., isServiceProvider(), isEventListener()). |
Custom Filter classes |
Medium |
How can I help you explore Laravel packages today?