Introduction

When you create a new PHP class and Composer's autoload cannot find it, you get "Class not found" errors even though the file exists. This happens because Composer's autoload map is a cached file that needs to be regenerated when new classes are added, especially when using classmap or files autoload types.

This is a common issue during development when creating new classes, moving files between directories, or changing namespace declarations.

Symptoms

  • PHP throws "Class 'App\\Services\\NewService' not found" for a newly created class
  • The file exists at the correct path but Composer's autoloader cannot find it
  • Running composer dump-autoload fixes the issue temporarily

Common Causes

  • Classmap autoload cache is stale and doesn't include the new class file
  • PSR-4 namespace does not match the directory structure
  • composer.json autoload configuration doesn't include the new directory

Step-by-Step Fix

  1. 1.Regenerate the autoload files: Run composer dump-autoload to rebuild the class map.
  2. 2.```bash
  3. 3.# Regenerate autoload files:
  4. 4.composer dump-autoload

# For classmap optimization (production): composer dump-autoload --optimize

# For classmap-authoritative (production, fastest): composer dump-autoload --classmap-authoritative ```

  1. 1.Verify PSR-4 namespace matches directory structure: Ensure namespace and path align.
  2. 2.```php
  3. 3.// composer.json:
  4. 4.{
  5. 5."autoload": {
  6. 6."psr-4": {
  7. 7."App\\": "src/"
  8. 8.}
  9. 9.}
  10. 10.}

// File: src/Services/NewService.php <?php namespace App\Services; // Must match App\ + Services/ path

class NewService { public function handle() { } } ```

  1. 1.Check for case-sensitivity issues in class names: Class names must match file names exactly.
  2. 2.```bash
  3. 3.# Find case mismatches between class names and file names:
  4. 4.find src/ -name "*.php" -exec grep -l "^class " {} \; | while read f; do
  5. 5.expected=$(basename "$f" .php)
  6. 6.actual=$(grep "^class " "$f" | head -1 | awk '{print $2}' | tr -d '{')
  7. 7.if [ "$expected" != "$actual" ]; then
  8. 8.echo "Mismatch in $f: file=$expected, class=$actual"
  9. 9.fi
  10. 10.done
  11. 11.`

Prevention

  • Run composer dump-autoload as part of your deployment process
  • Use PSR-4 autoloading instead of classmap for development
  • Enable classmap-authoritative in production for performance
  • Add a pre-commit hook that validates namespace-to-path alignment