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.
Installation:
composer require composer/class-map-generator
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)
}
First Use Case:
$generator = new ClassMapGenerator();
$generator->scanPaths(app_path('Console/Commands'));
$map = $generator->getClassMap()->getMap();
// Cache $map in a file or Redis for reuse.
ClassMapGenerator and ClassMap classes in the README.bootstrap/cache or SplClassLoader.// 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;
}
// 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];
}
});
$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));
}
$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));
}
}
$this->app->singleton(ClassMapGenerator::class, function () {
return new ClassMapGenerator();
});
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!');
}
}
composer install or vendor:publish:
use Illuminate\Foundation\Bootstrap\LoadConfiguration;
class RegenerateClassMap extends LoadConfiguration
{
public function bootstrap()
{
if (app()->runningInConsole()) {
$this->call('generate:classmap');
}
}
}
$autoloader = require __DIR__ . '/../vendor/autoload.php';
$customMap = include __DIR__ . '/../../storage/framework/class-map.php';
foreach ($customMap as $class => $path) {
$autoloader->addClassMap($class, $path);
}
Ambiguous Classes:
$classMap->getAmbiguousClasses() to detect and resolve conflicts manually.filterByNamespace() to narrow scope:
$generator->filterByNamespace('App\\', true); // Only include subnamespaces of 'App'
PSR Violations:
$generator->setBaseNamespace('App\\');
$violations = $generator->getClassMap()->getPsrViolations();
$classMap->clearPsrViolationsByPath(app_path('Tests'));
Performance:
node_modules) can be slow.scanPaths() with specific directories and exclude unnecessary paths:
$generator->scanPaths(app_path('Modules'), ['exclude' => ['Tests', 'vendor']]);
Windows Paths:
$paths = array_map('str_replace', ['\\', '/'], $paths);
Stream Wrappers:
zip://) may fail on PHP 8.5+.composer update composer/class-map-generator
Dynamic Classes:
eval()) won’t appear in the map.PHP 8.4+ Nullability:
$classMap = $generator->getClassMap();
foreach ($classMap->getWarnings() as $warning) {
Log::warning($warning);
}
$classMap->getRawPsrViolations() to debug PSR compliance issues:
$rawViolations = $classMap->getRawPsrViolations();
dd($rawViolations);
$start = microtime(true);
$generator->scanPaths(app_path('Modules'));
$time = microtime(true) - $start;
Log::info("Scan time: {$time}s");
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
How can I help you explore Laravel packages today?