Weave 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

Parser Reflection Laravel Package

goaop/parser-reflection

Parser Reflection brings PHP's Reflection API to static analysis: parse source files into an AST and introspect classes, methods, and properties without autoloading, including, or executing code. Drop-in compatible with native Reflection classes for analyzers, generators, and IDE tooling.

View on GitHub
Deep Wiki
Context7

Getting Started

goaop/parser-reflection is best treated as a development/static-analysis dependency, not a normal Laravel runtime package. It gives you ReflectionClass, ReflectionMethod, ReflectionProperty, ReflectionFile, etc. backed by source AST instead of loaded classes.

  1. Check PHP and parser constraints before installing. The current 5.x line requires PHP >=8.5 and nikic/php-parser:^5.9. Many Laravel apps are still on PHP 8.2–8.4, so Composer may resolve an older major. Verify that major against your Laravel/PHP version before adopting. For tooling-only use:
    composer require --dev goaop/parser-reflection
    
  2. No Laravel service provider is needed. Composer auto-initialization is enough. If your project uses a custom autoloader, implement Go\ParserReflection\LocatorInterface and pass it to ReflectionEngine::init().
  3. Read these first: the README, docs/reflection_file.md, docs/reflection_file_namespace.md, then the source for ReflectionClass, ReflectionEngine, and ComposerLocator.
  4. First use case: an Artisan command that inventories app classes without bootstrapping them. For example, scan app/Models or app/Http/Controllers and report methods, properties, attributes, and docblocks.
use Go\ParserReflection\ReflectionFile;

$file = new ReflectionFile(base_path('app/Models/User.php'));

foreach ($file->getFileNamespaces() as $namespace) {
    foreach ($namespace->getClasses() as $class) {
        $this->line($class->getName());

        foreach ($class->getMethods() as $method) {
            $this->line('  method: ' . $method->getName());
        }

        foreach ($class->getProperties() as $property) {
            $this->line('  property: ' . $property->getName());
        }
    }
}

For known PSR-4 classes, new \Go\ParserReflection\ReflectionClass(\App\Models\User::class) works without instantiating User; using User::class does not load the class.

Implementation Patterns

  • Use file-first discovery for directories. ReflectionFile is the reliable entry point for arbitrary files, generated code, or classes not yet resolvable through Composer. Iterate namespaces via getFileNamespaces(), then classes via getClasses().
  • Use class-first reflection for known FQCNs. new \Go\ParserReflection\ReflectionClass($fqcn) is convenient when Composer can locate the file. It is the closest drop-in replacement for native \ReflectionClass.
  • Build architecture guardrails in CI. Good Laravel-specific checks include: every controller ends in Controller; every public controller method has a return type; every model extends Model; jobs/events follow naming conventions; custom attributes are only used on supported targets. Run these in an Artisan command or CI job, not in request middleware.
  • Extract stable DTOs instead of caching reflection objects. Collect arrays/scalars such as class name, file path, method names, parameter types, attributes, and docblocks. Cache those DTOs keyed by file path and mtime; do not serialize ReflectionClass instances.
  • Use it as a safe substitute where a \ReflectionClass is expected. Parser reflection classes extend native reflection classes, so a service type-hinting \ReflectionClass can often accept them. Keep the boundary clear: metadata methods are safe; object-manipulation methods may trigger native fallback.
  • Integrate at Laravel tooling edges. Common places are Artisan commands, code generators, documentation generators, static-analysis checks, and package development scripts. Avoid putting source parsing in hot HTTP paths or per-request service providers.
  • Use attributes for metadata extraction. getAttributes() lets you inspect Laravel/custom attributes without loading the class. On 5.x, named attribute arguments are keyed by name, matching native reflection. Only call newInstance() when you explicitly accept autoloading and attribute-constructor execution.
  • Add a custom locator for non-Composer modules. If your app uses a custom module loader, generated class maps, or a non-PSR-4 structure, implement LocatorInterface and initialize ReflectionEngine once in your bootstrap/tooling command.
  • Fall back to nikic/php-parser for AST details the reflection wrapper does not expose. Use parser reflection for the familiar reflection API; use raw AST nodes for precise syntax-level rules.
  • Keep native reflection for behavior verification. In tests or local tooling where booting Laravel is acceptable, compare parser reflection output with native reflection for a small fixture set. This catches version-specific divergence early.

Example architecture check:

use Go\ParserReflection\ReflectionClass;

$class = new ReflectionClass($fqcn);

foreach ($class->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
    if ($method->getReturnType() === null) {
        $this->warn("Missing return type: {$class->getName()}::{$method->getName()}");
    }
}

Gotchas and Tips

  • Version compatibility is the biggest risk. The 5.x line requires PHP >=8.5; Laravel projects on PHP 8.2–8.4 will need an older major. The package has a small adoption footprint in the supplied metadata, so pin it exactly, keep it dev-only, and have a fallback plan. If Composer conflicts with PHPStan, Rector, or another nikic/php-parser consumer, do not force it into the runtime dependency graph.
  • The locator still depends on Composer knowing where the class lives. ComposerLocator asks the Composer autoloader for a filename. New files may require composer dump-autoload; class aliases and anonymous classes are poor fits. If class-first reflection fails, switch to ReflectionFile on the actual path.
  • “No loading” applies only to metadata methods. Per the README, methods that require object manipulation—invoke(), invokeArgs(), setAccessible(), and similar—can trigger native class loading and fallback. Once that happens, you are no longer in pure static-analysis mode.
  • Defaults are source-level, not runtime-evaluated. A property default using env(), config(), concatenation, or other expressions may not equal the runtime value. This matters for Laravel model $fillable, $casts, and config-driven properties. Treat getDefaultValue()/getDefaultProperties() as AST information, not application state.
  • Eloquent magic is invisible. Parser reflection sees declared methods and properties only. It cannot infer database columns, dynamic relations, accessor/mutator magic, or runtime model attributes. Use it for declared structure, not schema discovery.
  • Catch per-file/per-class ReflectionExceptions. A single parse failure should not abort a directory scan. Log the file path, class name, and exception message, then continue.
  • Respect documented 5.x limitations. Parameter doc comments written after a parameter can be dropped by PHP-Parser; partial-function placeholders in constant-expression positions can throw ReflectionException; scope-aware property readability resolves statically and deliberately does not autoload scope classes.
  • Attribute argument shape changed in 5.x. Named attribute arguments are keyed by name in ReflectionAttribute::getArguments(). If you are upgrading from 4.x, adjust code that assumed a positional list.
  • Debug locator problems with ReflectionFile first. If new ReflectionClass($fqcn) fails, parse the expected file directly with ReflectionFile. If that works, the issue is class location/autoloading, not AST parsing. Check absolute paths and run composer dump-autoload -o when using optimized classmaps.
  • Do not scan thousands of files per request. Parsing has real CPU and memory cost. Batch scans in Artisan/CI, chunk directories, cache extracted DTOs, and invalidate on deploy or source mtime changes. Avoid scanning vendor/, storage/, and generated cache directories.
  • Long-running workers need cache discipline. In queue workers or Octane, stale DTO caches can survive code changes. Clear custom analysis caches on deployment. Avoid holding large reflection graphs longer than necessary.
  • There is no Laravel config file or service provider to tune. Extension points are primarily LocatorInterface, ReflectionEngine::init(), and composition around the reflection objects. For unsupported AST details, use nikic/php-parser directly rather than trying to patch behavior through Laravel config.
  • Treat parsing as resource-sensitive. It does not execute source code, but parsing very large or untrusted files can still consume significant CPU/memory. Do not expose a public endpoint that parses arbitrary user-uploaded PHP files.
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator