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

Class Map Generator Laravel Package

composer/class-map-generator

Generate PHP class maps by scanning directories for classes, interfaces, traits, and enums. Create a quick symbol-to-file map or use the generator for multi-path scans, sorting, and reporting ambiguous class definitions. MIT licensed; PHP 7.2+.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require composer/class-map-generator
    

    Ensure your project meets the PHP 7.2+ requirement.

  2. First Use Case: Generate a class map for a directory (e.g., Laravel’s app folder):

    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $map = ClassMapGenerator::createMap(app_path());
    foreach ($map as $class => $path) {
        // Process each class and its path (e.g., log, cache, or validate)
        file_put_contents(
            storage_path('framework/class-map.php'),
            '<?php return ' . var_export($map, true) . ';'
        );
    }
    

    Output: A raw array of class => file_path pairs, ready for custom autoloading or analysis.

  3. Where to Look First:

    • README.md: Quickstart examples.
    • ClassMapGenerator: Core API methods (scanPaths(), getClassMap()).
    • ClassMap: Inspect warnings (getAmbiguousClasses(), getPsrViolations()).

Implementation Patterns

Core Workflows

1. Pre-Generating Class Maps for Performance

  • Use Case: Reduce Laravel cold starts in CLI tools or APIs.
  • Pattern:
    $generator = new ClassMapGenerator();
    $generator->scanPaths([
        app_path('Http/Controllers'),
        app_path('Modules'),
    ]);
    $classMap = $generator->getClassMap()->sort();
    file_put_contents(
        storage_path('framework/preloaded-class-map.php'),
        '<?php return ' . var_export($classMap->getMap(), true) . ';'
    );
    
  • Integration:
    • Load the cached map in bootstrap/app.php:
      $preloadedMap = include storage_path('framework/preloaded-class-map.php');
      spl_autoload_register(function ($class) use ($preloadedMap) {
          if (isset($preloadedMap[$class])) {
              require $preloadedMap[$class];
          }
      });
      

2. Dynamic Plugin/Module Autoloading

  • Use Case: Load classes from user-uploaded modules or plugins.
  • Pattern:
    $generator = new ClassMapGenerator();
    $modulePath = storage_path('app/Modules/' . $moduleName);
    if (is_dir($modulePath)) {
        $generator->scanPaths($modulePath);
        $moduleMap = $generator->getClassMap()->getMap();
        // Merge into a custom autoloader or Laravel's service provider.
    }
    

3. PSR Compliance Validation

  • Use Case: Enforce PSR-4 namespaces in a codebase.
  • Pattern:
    $generator = new ClassMapGenerator();
    $generator->scanPaths(app_path());
    $violations = $generator->getClassMap()->getPsrViolations();
    foreach ($violations as $violation) {
        Log::warning("PSR Violation: {$violation->getMessage()}");
    }
    

4. Handling Ambiguous Classes

  • Use Case: Debug namespace collisions (e.g., same class in multiple files).
  • Pattern:
    $generator = new ClassMapGenerator();
    $generator->scanPaths([
        app_path('Providers'),
        vendor_path('package/providers'),
    ]);
    $ambiguous = $generator->getClassMap()->getAmbiguousClasses();
    if (!empty($ambiguous)) {
        throw new \RuntimeException(
            'Ambiguous classes detected: ' . implode(', ', array_keys($ambiguous))
        );
    }
    

Laravel-Specific Integrations

Custom Autoloader Service Provider

namespace App\Providers;

use Composer\ClassMapGenerator\ClassMapGenerator;
use Illuminate\Support\ServiceProvider;

class ClassMapServiceProvider extends ServiceProvider
{
    public function register()
    {
        $map = ClassMapGenerator::createMap(app_path('Custom'));
        spl_autoload_register(function ($class) use ($map) {
            if (isset($map[$class])) {
                require $map[$class];
            }
        });
    }
}

Artisan Command for Class Map Generation

namespace App\Console\Commands;

use Composer\ClassMapGenerator\ClassMapGenerator;
use Illuminate\Console\Command;

class GenerateClassMap extends Command
{
    protected $signature = 'classmap:generate {--path= : Path to scan}';
    protected $description = 'Generate a class map for custom autoloading';

    public function handle()
    {
        $path = $this->option('path') ?: app_path();
        $map = ClassMapGenerator::createMap($path);
        file_put_contents(
            storage_path('framework/custom-class-map.php'),
            '<?php return ' . var_export($map, true) . ';'
        );
        $this->info("Class map generated at storage/framework/custom-class-map.php");
    }
}

Dynamic Class Loading for Feature Flags

use Composer\ClassMapGenerator\ClassMapGenerator;

$featureEnabled = config('features.experimental_api');
if ($featureEnabled) {
    $generator = new ClassMapGenerator();
    $generator->scanPaths(app_path('Features/Experimental'));
    $map = $generator->getClassMap()->getMap();
    spl_autoload_register(function ($class) use ($map) {
        if (isset($map[$class])) {
            require $map[$class];
        }
    });
}

Gotchas and Tips

Pitfalls

  1. Ambiguous Class Warnings:

    • Issue: Scanning multiple paths may flag the same class as ambiguous if it exists in more than one location.
    • Fix: Use getAmbiguousClasses() to inspect and resolve conflicts manually:
      $ambiguous = $generator->getClassMap()->getAmbiguousClasses();
      if (!empty($ambiguous)) {
          throw new \RuntimeException("Ambiguous classes: " . implode(', ', array_keys($ambiguous)));
      }
      
  2. PSR Violation False Positives:

    • Issue: Classes in subdirectories may incorrectly trigger PSR violations if the base namespace isn’t configured.
    • Fix: Explicitly set the base namespace when scanning:
      $generator = new ClassMapGenerator();
      $generator->setBaseNamespace('App\\');
      $generator->scanPaths(app_path());
      
  3. Windows Path Normalization:

    • Issue: Paths may not resolve correctly across Windows/Linux environments.
    • Fix: Normalize paths before scanning:
      $paths = array_map('realpath', [$path1, $path2]);
      $generator->scanPaths($paths);
      
  4. Performance with Large Codebases:

    • Issue: Scanning vendor/ or monolithic apps can be slow.
    • Fix:
      • Exclude directories:
        $generator->scanPaths(app_path(), ['tests', 'storage']);
        
      • Use ClassMapGenerator::createMap() for one-off scans (faster than instantiating a generator).
  5. Stream Wrapper Limitations:

    • Issue: Scanning paths with custom stream wrappers (e.g., s3://) may fail on PHP 8.5+.
    • Fix: Ensure php_strip_whitespace isn’t disabled in disable_functions (fixed in v1.6.1).
  6. Enums and Modern PHP Features:

    • Issue: Older versions may not handle enums or PHP 8+ attributes correctly.
    • Fix: Use the latest version (v1.7.3+) for full support.

Debugging Tips

  • Inspect Raw Violations:
    $violations = $generator->getClassMap()->getRawPsrViolations();
    foreach ($violations as $violation) {
        echo "File: {$violation->getPath()}\n";
        echo "Rule: {$violation->getRule()}\n";
    }
    
  • Clear PSR Violations:
    $generator->getClassMap()->clearPsrViolationsByPath(app_path('Some/Invalid/File.php'));
    
  • Log Ambiguous Classes:
    foreach ($generator->getClassMap()->getAmbiguousClasses() as $class => $paths) {
        Log::error("Ambiguous class {$class} found in: " . implode(', ', $paths));
    }
    

Extension Points

  1. Custom Filters:

    • Extend ClassMapGenerator to filter classes by namespace or regex:
      $generator->filterByNamespace('App\\Modules\\*');
      
    • Or implement a custom ClassMapFilter interface.
  2. Post-Processing:

    • Modify the generated map before caching
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