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+.
Installation:
composer require composer/class-map-generator
Ensure your project meets the PHP 7.2+ requirement.
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.
Where to Look First:
scanPaths(), getClassMap()).getAmbiguousClasses(), getPsrViolations()).$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) . ';'
);
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];
}
});
$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.
}
$generator = new ClassMapGenerator();
$generator->scanPaths(app_path());
$violations = $generator->getClassMap()->getPsrViolations();
foreach ($violations as $violation) {
Log::warning("PSR Violation: {$violation->getMessage()}");
}
$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))
);
}
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];
}
});
}
}
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");
}
}
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];
}
});
}
Ambiguous Class Warnings:
getAmbiguousClasses() to inspect and resolve conflicts manually:
$ambiguous = $generator->getClassMap()->getAmbiguousClasses();
if (!empty($ambiguous)) {
throw new \RuntimeException("Ambiguous classes: " . implode(', ', array_keys($ambiguous)));
}
PSR Violation False Positives:
$generator = new ClassMapGenerator();
$generator->setBaseNamespace('App\\');
$generator->scanPaths(app_path());
Windows Path Normalization:
$paths = array_map('realpath', [$path1, $path2]);
$generator->scanPaths($paths);
Performance with Large Codebases:
vendor/ or monolithic apps can be slow.$generator->scanPaths(app_path(), ['tests', 'storage']);
ClassMapGenerator::createMap() for one-off scans (faster than instantiating a generator).Stream Wrapper Limitations:
s3://) may fail on PHP 8.5+.php_strip_whitespace isn’t disabled in disable_functions (fixed in v1.6.1).Enums and Modern PHP Features:
$violations = $generator->getClassMap()->getRawPsrViolations();
foreach ($violations as $violation) {
echo "File: {$violation->getPath()}\n";
echo "Rule: {$violation->getRule()}\n";
}
$generator->getClassMap()->clearPsrViolationsByPath(app_path('Some/Invalid/File.php'));
foreach ($generator->getClassMap()->getAmbiguousClasses() as $class => $paths) {
Log::error("Ambiguous class {$class} found in: " . implode(', ', $paths));
}
Custom Filters:
ClassMapGenerator to filter classes by namespace or regex:
$generator->filterByNamespace('App\\Modules\\*');
ClassMapFilter interface.Post-Processing:
How can I help you explore Laravel packages today?