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

Reflection Laravel Package

phpdocumentor/reflection

Static PHP code reflection library that parses one or more files (no execution) to build an object graph of your application's structure, including DocBlocks. Supports analyzing PHP versions from 5.2 up to your installed PHP version; useful for reflecting whole projects.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require phpdocumentor/reflection:~6.0

Add to composer.json under require-dev if only needed for testing/analysis.

  1. First Use Case:
    require 'vendor/autoload.php';
    
    $projectFactory = \phpDocumentor\Reflection\Php\ProjectFactory::createInstance();
    $project = $projectFactory->create('MyApp', [
        new \phpDocumentor\Reflection\File\LocalFile(app_path('Http/Controllers/UserController.php'))
    ]);
    
    // Access classes in the project
    $classes = $project->getClasses();
    foreach ($classes as $class) {
        echo $class->getName() . "\n";
    }
    

Key Entry Points

  • ProjectFactory: Core class for creating reflection projects.
  • Project: Container for all parsed files, classes, and metadata.
  • File\LocalFile: Wrapper for file paths (supports remote files via RemoteFile).
  • ClassReflection: Represents a class with methods, properties, and docblocks.

Implementation Patterns

1. Project-Wide Analysis

Workflow:

// Analyze entire Laravel app (adjust paths as needed)
$projectFactory = ProjectFactory::createInstance();
$project = $projectFactory->create('LaravelApp', [
    new LocalFile(base_path('app/Http/Controllers/*.php')),
    new LocalFile(base_path('app/Models/*.php')),
    new LocalFile(base_path('app/Providers/*.php')),
]);

// Query the project graph
$controllers = $project->getClasses()->filter(fn($class) =>
    str_contains($class->getFile()->getPath(), 'Controllers')
);

Integration Tips:

  • Cache Results: Serialize the Project object to avoid reprocessing:
    $cachePath = storage_path('reflection_cache.json');
    if (!file_exists($cachePath)) {
        $project = $projectFactory->create(...);
        file_put_contents($cachePath, serialize($project));
    } else {
        $project = unserialize(file_get_contents($cachePath));
    }
    
  • Laravel Service Provider:
    public function register()
    {
        $this->app->singleton('reflection.project', function () {
            return ProjectFactory::createInstance()->create('LaravelApp', [
                new LocalFile(base_path('app/**/*.php'))
            ]);
        });
    }
    

2. Class/Method Introspection

Common Use Cases:

// Get a specific class
$class = $project->getClass('App\\Http\\Controllers\\UserController');

// Inspect methods
foreach ($class->getMethods() as $method) {
    echo "Method: {$method->getName()}\n";
    echo "DocBlock: {$method->getDocBlock()}\n";
    echo "Return Type: {$method->getReturnType()}\n";
}

// Inspect properties
foreach ($class->getProperties() as $property) {
    echo "Property: {$property->getName()} (Type: {$property->getType()})\n";
}

Laravel-Specific Patterns:

  • Route Controller Binding:

    $routes = collect($project->getClasses())
        ->filter(fn($class) => $class->hasTag('Route'))
        ->map(fn($class) => [
            'controller' => $class->getName(),
            'methods' => $class->getMethods()->pluck('name')->toArray(),
        ]);
    
  • Middleware Analysis:

    $middleware = $project->getClasses()
        ->filter(fn($class) => $class->implementsInterface('Illuminate\\Contracts\\Auth\\Authenticatable'))
        ->pluck('name');
    

3. DocBlock and Annotation Parsing

Extracting PHPDoc Tags:

$class = $project->getClass('App\\Models\\User');
$docBlock = $class->getDocBlock();

if ($docBlock) {
    $tags = $docBlock->getTags();
    $author = $tags['author']?->getContent();
    $deprecated = $tags['deprecated']?->getContent();
}

Custom Annotations:

// Example: Parse `@api` tags for API documentation
$apiRoutes = $project->getClasses()
    ->filter(fn($class) => $class->getDocBlock()?->hasTag('api'))
    ->map(fn($class) => [
        'path' => $class->getDocBlock()->getTag('api')->getContent(),
        'class' => $class->getName(),
    ]);

4. Type Resolution and Expressions

Handling Default Arguments:

$method = $project->getClass('App\\Services\\UserService')->getMethod('find');
$parameters = $method->getParameters();

foreach ($parameters as $param) {
    $type = $param->getType();
    $defaultValue = $param->getDefaultValue();

    echo "Parameter: {$param->getName()}\n";
    echo "Type: {$type}\n";
    echo "Default: {$defaultValue}\n";
}

Expression Analysis (PHP 8.0+):

// Resolve complex default values (e.g., `[]`, `new DateTime()`)
$param = $method->getParameters()->first();
$expression = $param->getDefaultValueExpression();

if ($expression) {
    $resolvedType = $expression->getType();
    echo "Resolved Type: {$resolvedType}"; // e.g., `array`, `DateTime`
}

5. Attributes (PHP 8.0+)

Extracting Attributes:

$class = $project->getClass('App\\Http\\Middleware\\VerifyCsrfToken');
$attributes = $class->getAttributes();

foreach ($attributes as $attribute) {
    echo "Attribute: {$attribute->getName()}\n";
    $arguments = $attribute->getArguments();
    foreach ($arguments as $arg) {
        echo "  Argument: {$arg->getName()} = {$arg->getValue()}\n";
    }
}

Laravel-Specific:

// Find all middleware with `@Middleware` annotations
$middleware = $project->getClasses()
    ->filter(fn($class) => $class->hasAttribute('Illuminate\\Pipeline\\Middleware'))
    ->pluck('name');

Gotchas and Tips

Common Pitfalls

  1. File Path Handling:

    • Use LocalFile for local paths and RemoteFile for URLs (e.g., GitHub Gists).
    • Gotcha: Relative paths are resolved relative to the current working directory, not the script's location.
      // Fix: Use absolute paths
      $file = new LocalFile(realpath(__DIR__ . '/../app/Models/User.php'));
      
  2. PHP Version Compatibility:

    • The library supports PHP 5.2–8.5 by default, but some features (e.g., attributes, typed properties) require PHP 7.4+.
    • Debugging: If parsing fails, check the PHP version in phpDocumentor\Reflection\Php\Parser\ParserFactory.
  3. Circular Dependencies:

    • The library handles most circular references (e.g., traits, interfaces), but self-referencing constants may cause issues.
    • Fix: Upgrade to ~6.4.4 or later (see release notes).
  4. Memory Usage:

    • Parsing large codebases (e.g., full Laravel) can consume 1GB+ RAM.
    • Optimization: Process files in batches or use ProjectFactory::setMemoryLimit().
  5. DocBlock Parsing Quirks:

    • Gotcha: Multi-line docblocks with @param tags may not parse correctly if indentation varies.
    • Fix: Normalize docblocks before parsing:
      $docBlock = str_replace(["\r\n", "\r"], "\n", $docBlock);
      

Debugging Tips

  1. Parse Errors:

    • Enable verbose error messages:
      $projectFactory = ProjectFactory::createInstance();
      $projectFactory->setLogger(new \Monolog\Logger('reflection', [
          new \Monolog\Handler\StreamHandler('php://stderr', \Monolog\Logger::DEBUG),
      ]));
      
    • Errors now include file paths and line numbers (since v6.6.0).
  2. Type Resolution Issues:

    • If types are resolved as mixed or null, check:
      • The phpparser version (upgrade to ~4.0 for PHP 8.1+).
      • Custom type resolvers in ProjectFactory::addStrategy().
  3. Performance Profiling:

    • Use Xdebug to profile slow parsers:
      $projectFactory->setParser(new \phpDocumentor\Reflection\Php\Parser\Parser([
          'cacheFile' => storage_path('parser_cache'),
      ]));
      

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.
datacore/hub-sdk
alengo/sulu-http-cache-bundle
develia/commons
cuci/prototurk-sdk
cuci/prototurk-sdk-symfony
develia/geo-bundle
dreamzy/livewire-charts
touchestate-sdk/php-sdk
22h/doctrine-garbage-collection-bundle
imbo/imbo-coding-standard
visualbuilder/filament-lottie
servicioslineaonce/starter-kit
atomcoder/laravel-reorderable
irajul/filament-shadcn-theme
agtp/agtp-php
agtp/mod-php
centraldesktop/protobuf-php
trappistes/laravel-custom-fields
splash/sonata-admin
splash/metadata