- What is roave/better-reflection used for in a Laravel project?
- Better Reflection is a source-code reflection engine that parses PHP files with nikic/php-parser and exposes a ReflectionClass-shaped API over the AST without loading or executing the code. In Laravel it fits CI architecture rules, local diagnostics commands, and static analysis tooling. It is not intended for request handling, queue workers, middleware, or container introspection. For anything native reflection can already do at runtime, native reflection is faster.
- Is roave/better-reflection safe to use at runtime in Laravel?
- It is explicitly not for runtime usage; the README states performance is much worse than PHP's built-in reflection. Putting it on the request path, in queue workers, or in service provider boot adds a parser to the hot path. Use native reflection at runtime and reserve Better Reflection for development and CI-time capabilities.
- How do I install roave/better-reflection in a Laravel app?
- Install it with composer require roave/better-reflection, preferably as a dev dependency because it is a development and CI-time tool. It is MIT licensed, Composer-installable, and requires no services or infrastructure. Laravel's PSR-4 autoloading maps cleanly onto AutoloadSourceLocator.
- Does roave/better-reflection work with Laravel 10 or 11, and which PHP versions are supported?
- Better Reflection is framework-agnostic and does not ship Laravel-specific integration or version constraints. Major releases track PHP releases, so check Packagist and the compatibility matrix for the exact PHP version supported by the release you install. Laravel's PSR-4 autoloading works with AutoloadSourceLocator, but budget for major upgrades that come with a documented UPGRADE.md.
- How do I use Better Reflection in a Laravel CI job or test suite?
- Create a scoped source locator, such as a directory locator or ComposerSourceLocator, so analysis is deterministic and reproducible without booting the app. Call (new BetterReflection())->reflector()->reflectClass(Foo::class) or use StringSourceLocator with fixture code strings. This works well in a CI gate enforcing architecture or convention rules. Remember that rules can only assert on declared structure, not dynamic behavior.
- Can Better Reflection reflect on a class without loading it, or from a string of PHP code?
- Yes. It can reflect on classes that are not loaded and can parse classes directly from strings using StringSourceLocator. That string support is genuinely differentiating for scaffold generation and template analysis, but generation must be text or AST based because instantiation APIs are absent. Because classes are never loaded, you can inspect code that would fatal on load due to missing extensions or environment-specific dependencies.
- Why is Better Reflection slower than native PHP reflection, and how do I handle memory in a large Laravel app?
- It parses source files with nikic/php-parser and builds an AST, so there is real work per class, while native reflection reads already-loaded class metadata. Full-tree AST analysis of a mid-sized Laravel app can take seconds to minutes and hold significant memory. Deep inheritance resolution on Eloquent models and trait chains multiplies that cost. Scope locators to specific directories and add caching to keep CI time and memory predictable.
- Can Better Reflection see Laravel facades, container bindings, or Eloquent magic?
- No. It can only assert on declared structure, so facades, __call and __get proxies, macros, container resolution, model attribute casting, Blade, and Livewire hydration are invisible. Static analysis cannot see container bindings or facade resolution. Set expectations that rules can only check what is written in the code, not what happens dynamically at runtime.
- What Better Reflection features are unsupported for Laravel attribute, extension, and helper analysis?
- The compatibility matrix lists newInstance methods, ReflectionAttribute::newInstance(), getExtension(), and getClosureThis and getClosureScope as unsupported. Attribute-driven analysis of routes, validation, and authorization yields names and argument AST only, so you must interpret arguments yourself. Extension-provided classes such as Redis and Imagick are opaque. Global functions in app/helpers.php-style files need an explicit source locator or they are invisible.
- Is roave/better-reflection maintained, and how do I avoid nikic/php-parser conflicts with PHPStan or Rector?
- Maintenance signals are strong: a mutation-testing badge, a type-coverage gate, documentation, and an UPGRADE.md are present, and its real-world exposure is high because it is a transitive dependency of widely used PHP tooling. The main practical risk is php-parser version coupling, since PHPStan, Rector, PHP-CS-Fixer, and Better Reflection all constrain nikic/php-parser. Conflicting constraints are a common cause of un-installable dev dependencies in a single composer.json. Plan for isolation, such as a separate Composer context or dedicated tooling install, before adding it to a large Laravel project.