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.Regenerate the autoload files: Run composer dump-autoload to rebuild the class map.
- 2.```bash
- 3.# Regenerate autoload files:
- 4.composer dump-autoload
# For classmap optimization (production): composer dump-autoload --optimize
# For classmap-authoritative (production, fastest): composer dump-autoload --classmap-authoritative ```
- 1.Verify PSR-4 namespace matches directory structure: Ensure namespace and path align.
- 2.```php
- 3.// composer.json:
- 4.{
- 5."autoload": {
- 6."psr-4": {
- 7."App\\": "src/"
- 8.}
- 9.}
- 10.}
// File: src/Services/NewService.php <?php namespace App\Services; // Must match App\ + Services/ path
class NewService { public function handle() { } } ```
- 1.Check for case-sensitivity issues in class names: Class names must match file names exactly.
- 2.```bash
- 3.# Find case mismatches between class names and file names:
- 4.find src/ -name "*.php" -exec grep -l "^class " {} \; | while read f; do
- 5.expected=$(basename "$f" .php)
- 6.actual=$(grep "^class " "$f" | head -1 | awk '{print $2}' | tr -d '{')
- 7.if [ "$expected" != "$actual" ]; then
- 8.echo "Mismatch in $f: file=$expected, class=$actual"
- 9.fi
- 10.done
- 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