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:~7.0

Ensure vendor/autoload.php is included in your project.

  1. First Use Case: Reflect a single file to inspect its structure:

    use phpDocumentor\Reflection\Php\ProjectFactory;
    use phpDocumentor\Reflection\File\LocalFile;
    
    $factory = ProjectFactory::createInstance();
    $project = $factory->create(
        'My Project',
        [new LocalFile('path/to/YourClass.php')]
    );
    
    // Access the first class in the file
    $class = $project->getFiles()[0]->getClasses()[0];
    echo $class->getName(); // Output: YourClass
    
  2. Key Entry Points:

    • ProjectFactory::createInstance(): Initialize with default parser (PHP7 preferred, PHP5 fallback).
    • $factory->create(): Parse files into a Project object.
    • $project->getFiles(): Retrieve parsed files with their classes, traits, interfaces, and namespaces.

Implementation Patterns

1. Project-Wide Analysis

Workflow:

  • Reflect an entire codebase (e.g., Laravel app) by passing an array of LocalFile objects:
    $files = [];
    foreach (glob(app_path('*').'/*.php') as $file) {
        $files[] = new LocalFile($file);
    }
    $project = $factory->create('Laravel App', $files);
    
  • Use Case: Generate documentation, static analysis, or IDE tooling (e.g., autocompletion).

Integration Tip:

  • Cache the Project object to avoid reprocessing:
    $cacheKey = 'reflection_project_'.md5(filemtime(app_path('bootstrap/app.php')));
    $project = cache()->remember($cacheKey, now()->addHours(1), function () use ($factory) {
        return $factory->create('Laravel App', $files);
    });
    

2. Inspecting Elements

Common Operations:

  • Classes/Traits/Interfaces:
    $class = $project->getFiles()[0]->getClasses()[0];
    $methods = $class->getMethods(); // Array of Method objects
    $properties = $class->getProperties(); // Array of Property objects
    
  • Methods:
    $method = $class->getMethod('handleRequest');
    $parameters = $method->getParameters(); // Array of Parameter objects
    $returnType = $method->getReturnType(); // Type object (e.g., `string`, `array<int, Model>`)
    
  • DocBlocks:
    $docBlock = $class->getDocBlock();
    $tags = $docBlock->getTags(); // Array of Tag objects (e.g., `@param`, `@return`)
    

Laravel-Specific Example:

  • Inspect a controller’s route parameters:
    $controller = $project->findClass('App\Http\Controllers\YourController');
    $method = $controller->getMethod('__invoke');
    foreach ($method->getParameters() as $param) {
        echo "Parameter: {$param->getName()} (Type: {$param->getType()->__toString()})\n";
    }
    

3. Type Resolution

Advanced Use Case:

  • Resolve complex types (e.g., generics, unions) from default values:
    $parameter = $method->getParameters()[0];
    $defaultValue = $parameter->getDefaultValue();
    $resolvedType = $defaultValue->getType(); // Returns a `Type` object
    
  • Example: Extract type from a default array:
    $defaultValue = new \phpDocumentor\Reflection\Php\Value\Value([
        'key' => 'value',
        'items' => [1, 2, 3]
    ]);
    $type = $defaultValue->getType(); // Returns `array{string, int}`
    

Integration Tip:

  • Use TypeResolver to validate or transform types:
    use phpDocumentor\TypeResolver;
    $resolver = new TypeResolver();
    $type = $resolver->resolve($parameter->getType());
    

4. Custom File Strategies

Extend Functionality:

  • Override file processing (e.g., skip tests or vendor files):
    $factory = ProjectFactory::createInstance();
    $factory->setFileStrategy(new class implements \phpDocumentor\Reflection\Php\FileStrategy {
        public function process(\phpDocumentor\Reflection\File\File $file) {
            if (str_contains($file->getPath(), 'tests') || str_contains($file->getPath(), 'vendor')) {
                return null; // Skip
            }
            return $file;
        }
    });
    

5. Middleware for Post-Processing

Modify Reflection Data:

  • Add custom logic after parsing (e.g., enrich docblocks):
    $factory->addMiddleware(new class implements \phpDocumentor\Reflection\Middleware\Middleware {
        public function execute(\phpDocumentor\Reflection\Php\Project $project) {
            foreach ($project->getFiles() as $file) {
                foreach ($file->getClasses() as $class) {
                    $class->setCustomProperty('is_laravel_service', str_contains($class->getName(), 'Service'));
                }
            }
            return $project;
        }
    });
    

Gotchas and Tips

1. Breaking Changes (v6 → v7)

  • Type Objects: phpDocumentor\Reflection\Type was refactored. Update code using:
    // Old (v6):
    $type = $parameter->getType(); // Might return mixed types
    
    // New (v7):
    $type = $parameter->getType(); // Always returns a `Type` object (e.g., `String_`, `Array_`)
    
  • Expressions: String-based expressions (e.g., "new stdClass()") are now Expression objects. Use:
    $expression = $parameter->getDefaultValue()->getExpression();
    $type = $expression->getType(); // Resolve type from expression
    

2. Debugging Tips

  • Parse Errors: Include file paths/line numbers in errors:
    try {
        $project = $factory->create('Project', [$file]);
    } catch (\phpDocumentor\Reflection\Exception $e) {
        echo "Error in {$e->getFile()}:{$e->getLine()}: {$e->getMessage()}\n";
    }
    
  • Memory Usage: Static reflection is lightweight, but large projects may still require:
    $factory->setParserOptions(['prettyPrint' => true]); // Reduce memory for complex files
    

3. Performance Quirks

  • Parser Version: Defaults to PHP7. For PHP5 compatibility:
    $factory = ProjectFactory::createInstance('php5');
    
  • Caching: Cache Project objects or individual elements (e.g., classes) to avoid reprocessing:
    cache()->forever('reflection_class_'.$class->getFqsen(), $class);
    

4. Common Pitfalls

  • Self-Referenced Constants: Fixed in v6.4.4. If you encounter issues, ensure you’re using ~7.0:
    composer require phpdocumentor/reflection:~7.0
    
  • DocBlock Parsing: Invalid tags (e.g., @custom) won’t throw exceptions but return InvalidTag objects:
    $docBlock = $class->getDocBlock();
    foreach ($docBlock->getTags() as $tag) {
        if ($tag instanceof \phpDocumentor\Reflection\DocBlock\Tag\InvalidTag) {
            echo "Invalid tag: {$tag->getContent()}\n";
        }
    }
    
  • PHP 8+ Features: Ensure your PHP version matches the target (e.g., PHP 8.5 for array{...} syntax):
    $factory->setParserOptions(['phpVersion' => '8.5']);
    

5. Extension Points

  • Custom Factories: Extend \phpDocumentor\Reflection\Php\Factory\AbstractFactory to handle edge cases (e.g., custom attributes).
  • Type Resolver: Override \phpDocumentor\TypeResolver\Resolver for custom type logic (e.g., Laravel collections):
    $resolver = new class extends \phpDocumentor\TypeResolver\Resolver {
        protected function resolveCollectionType(\phpDocumentor\Reflection\Type $type) {
            return new \phpDocumentor\Reflection\Type\Object_('
    
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle