Composer Class Map Generator

repository·main·Indexed 42 days ago

https://github.com/composer/class-map-generator

A PHP utility library for scanning code to generate class maps, mapping classes, interfaces, traits, and enums to their file paths. It supports standard class map generation as well as PSR-0 and PSR-4 autoloading validation, providing tools to detect ambiguous class resolutions and PSR violations. Requires PHP 7.2 or higher.

Tokens
2.3K
Snippets
8
Records
13
Agent score
51%

What's inside Composer Class Map Generator

  1. Advanced class map generation with scanPaths()

    main

    For complex workflows, instantiate a ClassMapGenerator object. This allows you to scan multiple paths incrementally and provides access to a ClassMap object that includes metadata like warnings and ambiguous class resolutions.

    Workflow:

    1. Instantiate ClassMapGenerator.
    2. Call scanPaths(string $path) for each directory you wish to include.
    3. Call getClassMap() to retrieve a ClassMap object.
    4. Use getClassMap()->getMap() to access the resulting map.
    5. Use getClassMap()->getAmbiguousClasses() to identify symbols that map to multiple paths.
    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $generator = new ClassMapGenerator;
    $generator->scanPaths('path/to/scan');
    $generator->scanPaths('path/to/scan2');
    
    $classMap = $generator->getClassMap();
    $classMap->sort(); // optionally sort classes alphabetically
    foreach ($classMap->getMap() as $symbol => $path) {
        // do your thing
    }
    
    foreach ($classMap->getAmbiguousClasses() as $symbol => $paths) {
        // warn user about ambiguous class resolution
    }
  2. How PSR-0 and PSR-4 autoloading works in ClassMapGenerator

    main

    When using scanPaths() with $autoloadType set to 'psr-0' or 'psr-4', the generator doesn't just map every class it finds. Instead, it validates that the class name matches the file path according to the standard:

    • PSR-4: The class name must match the directory structure relative to the provided $namespace and $path.
    • PSR-0: Similar to PSR-4, but also handles underscores in class names as directory separators.

    If a class is found in a file but does not comply with the specified standard, the generator will skip it and record a violation in the ClassMap object. Note that when using these modes, $path must be a string and $namespace must be provided.

  3. Scan a directory for a class map

    main

    To quickly scan a directory and extract a map of all classes, interfaces, traits, and enums to their respective file paths, use the static ClassMapGenerator::createMap() method. This returns an associative array where the keys are the symbol names and the values are the file paths.

    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $map = ClassMapGenerator::createMap('path/to/scan');
    foreach ($map as $symbol => $path) {
        // do your thing
    }
  4. Generate a class map using ClassMapGenerator::createMap()

    main

    The simplest way to generate a class map for a specific path is to use the static createMap() method. This method instantiates a new generator, scans the provided path, and returns an associative array where keys are class names and values are the absolute paths to the files containing them.

    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $map = ClassMapGenerator::createMap('/path/to/project/src');
    // Returns array<class-string, non-empty-string>
  5. Use the ClassMap class to manage symbol-to-path mappings

    main

    The Composer\ClassMapGenerator\ClassMap class is the primary container for the generated class map. It stores mappings from class names to their file paths, tracks ambiguous class definitions (where the same class name exists in multiple files), and records PSR-0/4 autoloading violations.

    Key capabilities:

    • Retrieve the map: Use getMap() to get the full array of class-name => path mappings.
    • Check for existence: Use hasClass($className) to verify if a class is present, or getClassPath($className) to retrieve its specific path.
    • Handle ambiguity: Use getAmbiguousClasses() to identify classes that appear in multiple locations.
    • Detect PSR violations: Use getPsrViolations() to retrieve warnings about classes that do not follow PSR-0/4 directory structures.
  6. Scan paths with ClassMapGenerator::scanPaths()

    main

    For more control, instantiate ClassMapGenerator and use the scanPaths() method. This allows you to specify autoloading standards (PSR-0 or PSR-4), filter by namespace, and exclude specific files or directories.

    Parameters:

    • $path: A string path, an array of SplFileInfo objects, or a Traversable of SplFileInfo (e.g., from Symfony Finder).
    • $excluded (optional): A regex string that matches file paths to be excluded from the scan.
    • $autoloadType (optional): The autoloading standard to use. Must be one of: 'classmap', 'psr-0', or 'psr-4'. Defaults to 'classmap'.
    • $namespace (optional): A namespace prefix to filter by. Required if using 'psr-0' or 'psr-4'.
    • $excludedDirs (optional): An array of directory names to exclude relative to the $path.
    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $generator = new ClassMapGenerator(['php', 'inc']);
    $generator->scanPaths(
        '/path/to/src',
        '/regex/to/exclude',
        'psr-4',
        'App\\',
        ['vendor', 'tests']
    );
    
    $map = $generator->getClassMap()->getMap();
  7. Configure ClassMapGenerator extensions

    main

    When instantiating ClassMapGenerator, you can specify which file extensions should be scanned for classes. By default, it scans for .php and .inc files.

    // Only scan .php files
    $generator = new ClassMapGenerator(['php']);
    use Composer\ClassMapGenerator\ClassMapGenerator;
    
    $generator = new ClassMapGenerator(['php', 'inc']);
  8. Avoid duplicate scans in ClassMapGenerator

    main

    If you are calling scanPaths() multiple times on overlapping directory structures (for example, scanning a specific namespace after scanning a broad directory), you can prevent the same file from being processed twice by using avoidDuplicateScans(). This requires providing a FileList instance to track already scanned files.

    use Composer\ClassMapGenerator\ClassMapGenerator;
    use Composer\ClassMapGenerator\FileList;
    
    $generator = new ClassMapGenerator();
    $scannedFiles = new FileList();
    
    $generator->avoidDuplicateScans($scannedFiles);
    $generator->scanPaths('/path/to/broad/dir');
    $generator->scanPaths('/path/to/specific/dir'); // Files already in $scannedFiles will be skipped
  9. Retrieve ambiguous classes and filter duplicates

    main

    When the same class name is found in multiple files, it is recorded as an ambiguous class. You can retrieve these using getAmbiguousClasses($duplicatesFilter).

    By default, the generator ignores paths that look like test, fixture, example, or stub directories to reduce noise.

    Parameters:

    • $duplicatesFilter (string|false):
      • A regex string used to exclude paths. The default is {/(test|fixture|example|stub)s?/}i.
      • Pass false to disable filtering and return all duplicate paths found.
      • Passing true will result in an InvalidArgumentException.
    // Get all ambiguous classes, including those in test/ or fixture/ directories
    $ambiguous = $classMap->getAmbiguousClasses(false);
    
    // Use a custom regex to filter duplicates
    $ambiguous = $classMap->getAmbiguousClasses('/exclude-me/i');