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

Better Reflection Laravel Package

roave/better-reflection

Enhanced PHP reflection for static analysis: reflect classes without loading them, from PHP code strings or closures, extract AST from functions/methods, and read type declarations and docblocks. Feature-rich but slower than native reflection.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation: Add to composer.json:
    composer require roave/better-reflection
    
  2. First Use Case: Reflect a class without autoloading it:
    use Roave\BetterReflection\BetterReflection;
    
    $reflector = (new BetterReflection())->reflector();
    $class = $reflector->reflectClass(\App\Models\User::class);
    

Where to Look First

  • Core Docs: Start with docs/usage.md for basic patterns.
  • Feature Matrix: Check docs/features.md for supported capabilities (e.g., AST extraction, closure reflection).
  • Compatibility: Review docs/compatibility.md to avoid unsupported methods (e.g., newInstance).

Implementation Patterns

1. Static Analysis Workflows

Pattern: Use BetterReflection for pre-runtime analysis (e.g., validation, code generation).

// Validate method signatures dynamically
$method = $reflector->reflectMethod(\App\Services\Payment::class, 'process');
$params = $method->getParameters();
foreach ($params as $param) {
    if (!$param->hasType() && $param->isOptional()) {
        throw new \RuntimeException("Missing type hint for optional param: {$param->getName()}");
    }
}

2. AST-Based Tooling

Pattern: Extract Abstract Syntax Trees (AST) for custom logic (e.g., linting, refactoring).

$class = $reflector->reflectClass(\App\Jobs\QueueJob::class);
$ast = $class->getMethod('handle')->getDocComment(); // Or use `getMethodBodyNodes()` for AST

3. Closure Reflection

Pattern: Inspect closures (e.g., for middleware or event listeners).

$closure = fn($x) => $x * 2;
$reflection = (new BetterReflection())->reflector()->reflectClosure($closure);
$params = $reflection->getParameters(); // Analyze closure signature

4. Line-Specific Reflection

Pattern: Find declarations at specific file lines (e.g., for IDE plugins or error pinpointing).

$finder = (new BetterReflection())->findReflectionsOnLine();
$reflection = $finder(app_path('Http/Controllers/UserController.php'), 42);
if ($reflection instanceof \Roave\BetterReflection\Reflection\ReflectionMethod) {
    // Handle method reflection
}

5. Custom Source Locators

Pattern: Override autoloading for non-standard paths (e.g., vendor-agnostic reflection).

use Roave\BetterReflection\SourceLocator\SingleFileSourceLocator;

$locator = new SingleFileSourceLocator('/custom/path/ToClass.php');
$reflector = new \Roave\BetterReflection\Reflector\ClassReflector($locator);
$class = $reflector->reflectClass('ToClass');

6. Type-Driven Validation

Pattern: Enforce type contracts (e.g., for DTOs or API responses).

$method = $reflector->reflectMethod(\App\Actions\CreateUser::class, 'execute');
$returnType = $method->getReturnType();
if ($returnType && $returnType->getName() !== \App\DTO\User::class) {
    throw new \InvalidArgumentException("Method must return User DTO");
}

Gotchas and Tips

Performance Caveats

  • Runtime Penalty: Avoid using BetterReflection for runtime operations (e.g., in loops or hot paths). Cache reflections:
    static $reflections = [];
    if (!isset($reflections[$className])) {
        $reflections[$className] = $reflector->reflectClass($className);
    }
    
  • AST Extraction: Parsing ASTs is expensive. Use sparingly (e.g., during deployment, not requests).

Debugging Tips

  1. Unsupported Methods: Check docs/compatibility.md before using methods like newInstance() or getClosureThis().
  2. Closure Limitations: Closures lack full runtime context (e.g., $this binding). Use reflectClosure() only for static analysis.
  3. File Not Found: If reflection fails, verify:
    • The class is autoloadable (use ComposerSourceLocator by default).
    • The file path is correct (use SingleFileSourceLocator for custom paths).

Extension Points

  1. Custom Reflectors: Implement Reflector\ReflectorInterface for domain-specific logic (e.g., database-backed reflection).
  2. Source Locator Chaining: Combine locators for hybrid setups:
    $locator = new \Roave\BetterReflection\SourceLocator\CompositeSourceLocator([
        new ComposerSourceLocator(),
        new SingleFileSourceLocator('/custom/path'),
    ]);
    
  3. AST Transformations: Extend BetterReflection\Reflection\ReflectionMethod to add custom node visitors for AST manipulation.

Common Pitfalls

  • Circular Dependencies: Reflection may fail if classes depend on each other during analysis. Use BetterReflection::create() with a SourceLocator to control loading order.
  • PHP 8+ Features: Ensure compatibility with PHP 8’s attributes, union types, etc. (tested up to PHP 8.3+).
  • Memory Usage: Large codebases (e.g., monorepos) may bloat memory. Limit reflection scope with SourceLocator filters.

Pro Tips

  • Leverage ReflectionClass::createFromName(): Simpler than BetterReflection for one-off cases:
    $class = \Roave\BetterReflection\Reflection\ReflectionClass::createFromName(\App\Model::class);
    
  • Combine with phpstan/phpdoc-parser: Use BetterReflection for type hints and phpdoc-parser for docblock analysis.
  • CI/CD Integration: Run static analysis during tests:
    // In PHPUnit tests
    $this->assertTrue($method->hasReturnType());
    $this->assertEquals(\stdClass::class, $method->getReturnType()->getName());
    
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.
codraw/framework-extra-bundle
codraw/messenger
codraw/security
codraw/mailer
codraw/contracts
codraw/profiling
codraw/dependency-injection
codraw/tester
codraw/core
nexmo/api-specification
capell-app/block-library
axium/identity
cetria/laravel-dummy-models
cetria/reflection-helper
agropredict/sso-auth-bundle
evolvestudio/spam-protection
datacore/hub-sdk
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony