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/enums and mapping symbols to file paths. Supports simple one-shot map creation or incremental scans with sortable results and reporting of ambiguous class resolutions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require composer/class-map-generator
    
  2. Basic Scan:

    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $map = ClassMapGenerator::createMap(app_path('Modules'));
    foreach ($map as $class => $path) {
        // Use the class-path mapping (e.g., cache for faster autoloading)
    }
    
  3. First Use Case:

    • Pre-generate class maps for Laravel CLI tools to reduce cold-start time:
      $generator = new ClassMapGenerator();
      $generator->scanPaths(app_path('Console/Commands'));
      $map = $generator->getClassMap()->getMap();
      // Cache $map in a file or Redis for reuse.
      

Where to Look First

  • API Reference: Focus on ClassMapGenerator and ClassMap classes in the README.
  • Laravel Integration: Explore how to merge generated maps with Laravel’s bootstrap/cache or SplClassLoader.
  • Performance: Note the 30% scan speedup in v1.7.3 for large codebases.

Implementation Patterns

Core Workflows

1. Pre-Generating Class Maps for Performance

// In a Laravel Artisan command or service provider
public function generateClassMap()
{
    $generator = new ClassMapGenerator();
    $generator->scanPaths([
        app_path('Modules'),
        database_path('Seeds'),
    ]);
    $classMap = $generator->getClassMap();
    $classMap->sort(); // Optional: Alphabetical order

    // Cache the map (e.g., to disk or Redis)
    file_put_contents(storage_path('framework/class-map.php'), '<?php return ' . var_export($classMap->getMap(), true) . ';');

    return $classMap;
}
  • Use Case: Reduce autoloading latency for CLI tools or high-traffic APIs.

2. Dynamic Class Loading (Plugins/Modules)

// Load classes dynamically based on user input
$generator = new ClassMapGenerator();
$generator->scanPaths(storage_path('plugins/' . $pluginId));
$map = $generator->getClassMap()->getMap();

// Register a custom autoloader
spl_autoload_register(function ($class) use ($map) {
    if (isset($map[$class])) {
        require $map[$class];
    }
});
  • Use Case: SaaS platforms with user-uploaded plugins or modular Laravel apps.

3. PSR Compliance Validation

$generator = new ClassMapGenerator();
$generator->setBaseNamespace('App\\Modules');
$generator->scanPaths(app_path('Modules'));

$classMap = $generator->getClassMap();
$violations = $classMap->getPsrViolations();

if (!empty($violations)) {
    throw new \RuntimeException('PSR violations found: ' . implode(', ', $violations));
}
  • Use Case: Enforce PSR-4 compliance in CI/CD pipelines.

4. Handling Ambiguous Classes

$generator = new ClassMapGenerator();
$generator->scanPaths([
    app_path('Providers'),
    app_path('Console'),
]);

$classMap = $generator->getClassMap();
$ambiguous = $classMap->getAmbiguousClasses();

if (!empty($ambiguous)) {
    foreach ($ambiguous as $class => $paths) {
        Log::warning("Ambiguous class '{$class}' found in: " . implode(', ', $paths));
    }
}
  • Use Case: Debug namespace collisions during refactoring.

Integration Tips

  • Laravel Service Provider: Bind the generator to the container for reuse:
    $this->app->singleton(ClassMapGenerator::class, function () {
        return new ClassMapGenerator();
    });
    
  • Artisan Commands: Create a generate:classmap command to pre-generate maps during deployment:
    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    class GenerateClassMapCommand extends Command
    {
        protected $signature = 'generate:classmap';
        protected $description = 'Pre-generate class maps for performance';
    
        public function handle()
        {
            $generator = new ClassMapGenerator();
            $generator->scanPaths(app_path('Modules'));
            $map = $generator->getClassMap()->getMap();
    
            file_put_contents(storage_path('framework/class-map.php'), '<?php return ' . var_export($map, true) . ';');
            $this->info('Class map generated!');
        }
    }
    
  • Event Listeners: Trigger class map regeneration after composer install or vendor:publish:
    use Illuminate\Foundation\Bootstrap\LoadConfiguration;
    
    class RegenerateClassMap extends LoadConfiguration
    {
        public function bootstrap()
        {
            if (app()->runningInConsole()) {
                $this->call('generate:classmap');
            }
        }
    }
    
  • Custom Autoloader: Merge generated maps with Laravel’s autoloader:
    $autoloader = require __DIR__ . '/../vendor/autoload.php';
    $customMap = include __DIR__ . '/../../storage/framework/class-map.php';
    
    foreach ($customMap as $class => $path) {
        $autoloader->addClassMap($class, $path);
    }
    

Gotchas and Tips

Pitfalls

  1. Ambiguous Classes:

    • Issue: Scanning multiple directories may produce ambiguous class names (same class in different files).
    • Fix: Use $classMap->getAmbiguousClasses() to detect and resolve conflicts manually.
    • Tip: Exclude test directories or use filterByNamespace() to narrow scope:
      $generator->filterByNamespace('App\\', true); // Only include subnamespaces of 'App'
      
  2. PSR Violations:

    • Issue: Classes outside the configured namespace may be included, violating PSR-4.
    • Fix: Enable PSR validation:
      $generator->setBaseNamespace('App\\');
      $violations = $generator->getClassMap()->getPsrViolations();
      
    • Tip: Clear violations by path if needed:
      $classMap->clearPsrViolationsByPath(app_path('Tests'));
      
  3. Performance:

    • Issue: Scanning large codebases (e.g., node_modules) can be slow.
    • Fix: Use scanPaths() with specific directories and exclude unnecessary paths:
      $generator->scanPaths(app_path('Modules'), ['exclude' => ['Tests', 'vendor']]);
      
    • Tip: Cache results in Redis or a file to avoid repeated scans.
  4. Windows Paths:

    • Issue: Path normalization may fail on Windows.
    • Fix: Ensure paths use forward slashes or normalize them:
      $paths = array_map('str_replace', ['\\', '/'], $paths);
      
  5. Stream Wrappers:

    • Issue: Scanning paths with stream wrappers (e.g., zip://) may fail on PHP 8.5+.
    • Fix: Update to v1.7.2+ which includes fixes for this:
      composer update composer/class-map-generator
      
  6. Dynamic Classes:

    • Issue: Classes generated at runtime (e.g., via eval()) won’t appear in the map.
    • Fix: Use runtime reflection for dynamic classes and combine with static maps.
  7. PHP 8.4+ Nullability:

    • Issue: Older versions may throw warnings about implicit nullability.
    • Fix: Update to v1.1.1+ which addresses this.

Debugging Tips

  • Log Warnings:
    $classMap = $generator->getClassMap();
    foreach ($classMap->getWarnings() as $warning) {
        Log::warning($warning);
    }
    
  • Inspect Raw Data: Use $classMap->getRawPsrViolations() to debug PSR compliance issues:
    $rawViolations = $classMap->getRawPsrViolations();
    dd($rawViolations);
    
  • Profile Scanning: Measure scan time for optimization:
    $start = microtime(true);
    $generator->scanPaths(app_path('Modules'));
    $time = microtime(true) - $start;
    Log::info("Scan time: {$time}s");
    

Extension Points

  1. Custom Filters: Extend ClassMapGenerator to add custom logic (e.g., exclude files by pattern):
    class CustomClassMapGenerator extends ClassMapGenerator
    {
        public function scanPaths($paths, array $options = [])
        {
            $options['exclude'] = array_merge($options
    
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.
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament