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
    

    Requires PHP 7.2+ (compatible with Laravel 7+).

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

    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $map = ClassMapGenerator::createMap(app_path());
    foreach ($map as $class => $path) {
        // Use $class and $path (e.g., log, cache, or validate)
    }
    
  3. Where to Look First:

    • ClassMapGenerator: Core class for scanning paths and generating maps.
    • ClassMap: Result object with methods like getMap(), getAmbiguousClasses(), and sort().
    • README’s "Basic Usage": Quickstart for one-off scans.
    • Release Notes (v1.7.3+): Performance improvements and bug fixes (e.g., PHP 8.5+ compatibility).

Implementation Patterns

Usage Patterns

1. One-Off Scans (Simple Workflows)

Use createMap() for ad-hoc discovery (e.g., CLI tools, migrations):

$map = ClassMapGenerator::createMap(base_path('plugins'));
// Process $map directly (no generator object needed).

2. Multi-Directory Scans (Modular Apps)

Scan multiple paths (e.g., Laravel modules, plugins) and merge results:

$generator = new ClassMapGenerator();
$generator->scanPaths(app_path('Modules'));
$generator->scanPaths(app_path('Plugins'));
$classMap = $generator->getClassMap();

3. Dynamic Autoloading (Runtime Loading)

Integrate with SplAutoloader or Laravel’s ClassLoader:

$map = ClassMapGenerator::createMap(storage_path('dynamic'));
foreach ($map as $class => $path) {
    if (!class_exists($class, false)) {
        require $path;
    }
}

4. PSR Compliance Checks

Validate namespaces against a base prefix (e.g., App\Modules\):

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

foreach ($classMap->getPsrViolations() as $violation) {
    // Log or fix violations (e.g., missing namespace).
}

5. Ambiguous Class Handling

Detect and resolve duplicate class names (e.g., User in App and Vendor):

$generator->scanPaths([app_path(), vendor_path()]);
$classMap = $generator->getClassMap();

foreach ($classMap->getAmbiguousClasses() as $class => $paths) {
    // Log or prioritize paths (e.g., prefer `app/` over `vendor/`).
}

Workflows

Laravel-Specific Patterns

  1. Artisan Commands/Migrations: Pre-generate class maps in boot() or handle() to avoid autoloading:

    protected function handle()
    {
        $map = ClassMapGenerator::createMap(app_path('Features'));
        // Cache $map for subsequent runs.
    }
    
  2. Service Providers: Register a custom autoloader in register():

    public function register()
    {
        $loader = new \Composer\Autoload\ClassLoader();
        $map = ClassMapGenerator::createMap(app_path('Extensions'));
        $loader->addClassMap($map);
        $loader->register();
    }
    
  3. CI/CD Optimization: Cache class maps in GitHub Actions:

    # .github/workflows/test.yml
    jobs:
      test:
        steps:
          - uses: actions/cache@v3
            with:
              path: ~/.cache/class-maps
              key: ${{ runner.os }}-class-maps
          - run: php artisan class-map:generate --cache
    
  4. Dynamic Plugin Loading: Scan a plugins/ directory at runtime:

    public function loadPlugins()
    {
        $generator = new ClassMapGenerator();
        $generator->scanPaths(storage_path('plugins'));
        $classMap = $generator->getClassMap();
    
        foreach ($classMap->getMap() as $class => $path) {
            if (str_starts_with($class, 'Plugin\\')) {
                $this->registerPlugin($class);
            }
        }
    }
    

Integration Tips

  • Combine with Laravel’s ClassLoader: Merge generated maps with Laravel’s autoloader:

    $loader = require base_path('vendor/autoload.php');
    $loader->addClassMap(ClassMapGenerator::createMap(app_path('Custom')));
    
  • Cache Results: Serialize ClassMap to JSON/cache:

    $map = ClassMapGenerator::createMap(app_path());
    file_put_contents(cache_path('class-map.json'), json_encode($map));
    
  • Exclude Directories: Skip tests/fixtures:

    $generator->scanPaths(app_path(), ['excludes' => ['tests', 'fixtures']]);
    
  • Stream Wrapper Support: Scan remote paths (e.g., S3, SFTP):

    $generator->scanPaths('s3://bucket/path');
    

Gotchas and Tips

Pitfalls

  1. Ambiguous Classes:

    • Issue: Scanning multiple paths (e.g., app/ + vendor/) may yield duplicate class names (e.g., User).
    • Fix: Use getAmbiguousClasses() to resolve conflicts or exclude paths:
      $generator->scanPaths(app_path());
      $generator->scanPaths(vendor_path('laravel/framework'));
      $ambiguous = $generator->getClassMap()->getAmbiguousClasses();
      
  2. PSR Violations:

    • Issue: Classes without namespaces or outside the base prefix trigger warnings.
    • Fix: Set a base namespace and validate:
      $generator->setBaseNamespace('App\\');
      $violations = $generator->getClassMap()->getPsrViolations();
      
  3. Performance:

    • Issue: Scanning large codebases (e.g., vendor/) is slow.
    • Fix:
      • Use scanPaths() incrementally (e.g., scan app/ first, then vendor/).
      • Cache results (see "Cache Results" above).
      • Exclude unnecessary directories (e.g., tests, node_modules).
  4. Windows Paths:

    • Issue: Path normalization fails on Windows.
    • Fix: Use realpath() or ensure paths are absolute:
      $generator->scanPaths(realpath(app_path()));
      
  5. Stream Wrappers:

    • Issue: PHP 8.5+ may fail with missing stream functions.
    • Fix: Update to v1.7.2+ or ensure allow_url_fopen is enabled.
  6. Dynamic Classes:

    • Issue: Classes generated at runtime (e.g., eval(), create_function()) won’t appear in maps.
    • Fix: Use reflection or OPcache for dynamic code.
  7. Enums and Modern PHP:

    • Issue: Enums or PHP 8+ features may not be parsed correctly in older versions.
    • Fix: Use v1.7.3+ for full PHP 8.x support.

Debugging

  1. Inspect Warnings:

    • Use getClassMap()->getWarnings() to debug scanning issues.
  2. Log Ambiguous Classes:

    foreach ($classMap->getAmbiguousClasses() as $class => $paths) {
        Log::warning("Ambiguous class {$class}: " . implode(', ', $paths));
    }
    
  3. Validate Paths:

    • Ensure paths are absolute and exist:
      if (!file_exists($path)) {
          throw new \RuntimeException("Path {$path} does not exist.");
      }
      
  4. Check PHP Version:

    • Confirm PHP 7.2+ (use php -v or PHP_VERSION_ID >= 70200).

Tips

  1. Sorting:

    • Alphabetically sort classes for consistent output:
      $classMap->sort();
      
  2. Exclude Patterns:

    • Skip specific files/dirs:
      $generator->scanPaths(app_path(), [
          'excludes' => ['*Test.php', 'Resources/views'],
          'includes' => ['*Service.php']
      ]);
      
  3. Combine with Laravel:

    • Use in AppServiceProvider@boot() to pre-load critical classes:
      public function boot()
      {
          $map = ClassMapGenerator::createMap(app_path('Core
      
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.
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky
spatie/mailcoach-vapor