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 to map classes/interfaces/traits/enums to file paths. Use a simple static helper or an advanced generator to scan multiple paths, sort results, and detect ambiguous class resolutions.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Steps

  1. Installation:

    composer require composer/class-map-generator
    

    Ensure your project uses PHP 7.2+ (compatible with Laravel 5.8+).

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

    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $map = ClassMapGenerator::createMap(__DIR__ . '/app');
    foreach ($map as $class => $path) {
        // Log or process discovered classes (e.g., validate PSR compliance)
        file_put_contents('classmap.log', "$class => $path\n", FILE_APPEND);
    }
    
  3. Where to Look First:

    • ClassMapGenerator: Core class for scanning paths and generating maps.
    • ClassMap: Result object with methods like getMap(), sort(), and getAmbiguousClasses().
    • Laravel Integration: Focus on bootstrap/app.php or a custom composer.json script (see Implementation Patterns).

Implementation Patterns

Core Workflows

1. Precompute Class Maps for Laravel

Use Case: Optimize autoloading in production (e.g., serverless, high-traffic APIs). Pattern:

  • Add a Composer script (composer.json):
    {
      "scripts": {
        "post-autoload-dump": [
          "Composer\\ClassMapGenerator\\ClassMapGenerator::generateMap(__DIR__ . '/app', __DIR__ . '/bootstrap/cache/classmap.php')"
        ]
      }
    }
    
  • Custom Script Class (for complex logic):
    // bootstrap/generate-classmap.php
    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $generator = new ClassMapGenerator();
    $generator->scanPaths(__DIR__ . '/app');
    $generator->scanPaths(__DIR__ . '/vendor/your-package');
    $generator->getClassMap()->sort();
    file_put_contents(__DIR__ . '/bootstrap/cache/classmap.php', '<?php return ' . var_export($generator->getClassMap()->getMap(), true) . ';');
    
  • Load in bootstrap/app.php:
    $classMap = require __DIR__ . '/cache/classmap.php';
    spl_autoload_register(function ($class) use ($classMap) {
        if (isset($classMap[$class])) {
            require $classMap[$class];
        }
    });
    

2. PSR Compliance Enforcement

Use Case: Catch namespace violations during CI/CD. Pattern:

$generator = new ClassMapGenerator();
$generator->scanPaths(__DIR__ . '/app');
$classMap = $generator->getClassMap();

$violations = $classMap->getPsrViolations();
if (!empty($violations)) {
    throw new \RuntimeException("PSR violations found:\n" . implode("\n", $violations));
}

3. Exclude Directories (e.g., Tests)

Use Case: Skip test files or fixtures from production maps. Pattern:

$generator = new ClassMapGenerator();
$generator->scanPaths(__DIR__ . '/app', ['exclude' => ['tests', 'fixtures']]);

4. Handle Ambiguous Classes

Use Case: Debug duplicate class names (e.g., User in App\User and Modules\User). Pattern:

$generator = new ClassMapGenerator();
$generator->scanPaths(__DIR__ . '/app');
$generator->scanPaths(__DIR__ . '/modules');

$classMap = $generator->getClassMap();
foreach ($classMap->getAmbiguousClasses() as $class => $paths) {
    error_log("Ambiguous class '$class' found in: " . implode(', ', $paths));
}

5. Stream Wrapper Support

Use Case: Scan remote paths (e.g., S3, Git repos) via s3:// or git:// wrappers. Pattern:

$generator = new ClassMapGenerator();
$generator->scanPaths('s3://your-bucket/path/to/code');

Laravel-Specific Integrations

Autoload Optimization

Replace Laravel’s default composer dump-autoload --optimize with a custom script:

composer dump-autoload --no-dev
php bootstrap/generate-classmap.php

Pros:

  • Faster than Composer’s optimizer for large codebases.
  • Fine-grained control over exclusions/ambiguities.

Plugin/System Integration

For modular apps (e.g., plugins, themes):

// In PluginManager.php
public function loadClasses(Plugin $plugin) {
    $generator = new ClassMapGenerator();
    $generator->scanPaths($plugin->getPath());
    $classMap = $generator->getClassMap();

    foreach ($classMap->getMap() as $class => $path) {
        if (str_starts_with($class, $plugin->getNamespace())) {
            $this->registerClass($class, $path);
        }
    }
}

Dynamic Class Loading

Combine with spl_autoload_register for hybrid static/dynamic loading:

$classMap = require __DIR__ . '/cache/classmap.php';
spl_autoload_register(function ($class) use ($classMap) {
    if (isset($classMap[$class])) {
        require $classMap[$class];
    }
});

// Fallback to Composer autoloader
spl_autoload_register();

Gotchas and Tips

Pitfalls

  1. Ambiguous Classes:

    • Issue: Scanning multiple paths (e.g., app/ + vendor/) may produce duplicate class names.
    • Fix: Use getAmbiguousClasses() to debug and manually resolve conflicts. Exclude problematic directories if possible.
  2. PSR Violations:

    • Issue: Classes without namespaces or with incorrect namespace prefixes trigger warnings.
    • Fix: Use getPsrViolations() in CI to fail builds early. Example:
      $violations = $classMap->getPsrViolations();
      if (!empty($violations)) {
          exit(1); // Fail CI
      }
      
  3. Windows Paths:

    • Issue: Path normalization may fail on Windows (C:\path\to\file.php).
    • Fix: Use realpath() or ensure paths are forward-slash normalized:
      $generator->scanPaths(str_replace('\\', '/', __DIR__ . '/app'));
      
  4. Stream Wrapper Quirks:

    • Issue: PHP 8.5+ may block stream wrapper functions (e.g., s3://).
    • Fix: Ensure allow_url_fopen is enabled or use php://filter wrappers as a fallback.
  5. Performance with Large Codebases:

    • Issue: Scanning 10K+ files can be slow.
    • Fix: Cache results or use ClassMapGenerator::createMap() for one-off scans.
  6. Aliased Use Statements:

    • Issue: use Foo\Bar as Baz; may cause parsing errors.
    • Fix: Upgrade to v1.3.4+ (fixed in #9).
  7. PHP 8.4+ Nullability:

    • Issue: Deprecation warnings for implicit nullability.
    • Fix: Use v1.1.1+ (fixed in #5).

Debugging Tips

  1. Log Warnings:

    $classMap = $generator->getClassMap();
    foreach ($classMap->getWarnings() as $warning) {
        error_log($warning);
    }
    
  2. Inspect Raw Data:

    $map = $generator->getClassMap()->getMap();
    print_r(array_slice($map, 0, 10)); // Show first 10 entries
    
  3. Validate Against Composer: Compare output with composer dump-autoload --no-dev --classmap-only:

    composer dump-autoload --no-dev --classmap-only > composer-classmap.php
    php -r '$map = require "composer-classmap.php"; print_r(array_keys($map));'
    

Extension Points

  1. Custom Filters: Extend ClassMapGenerator to filter classes by namespace or regex:

    $generator = new ClassMapGenerator();
    $generator->scanPaths(__DIR__ . '/app');
    $filteredMap = array_filter($generator->getClassMap()->getMap(), function ($class) {
        return str_starts_with($class, 'App\\');
    }, ARRAY_FILTER_USE_KEY);
    
  2. Post-Processing: Use ClassMap::sort()

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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport