← Debugging Guides

阅读中文版本

PHP Fatal error: Class Not Found — Composer Autoload Miss

Fix "Class not found" fatal errors by regenerating the Composer autoloader, matching PSR-4 namespace to directory, and clearing the opcache.

intermediatedebuggingphpcomposerautoload

Symptoms

  • Fatal error: Uncaught Error: Class "App\Service\Mailer" not found
  • Works locally but fails on the deployed server
  • A newly added class is not found until you manually edit something

Possible causes

  • The PSR-4 namespace prefix does not map to the actual directory path
  • The optimized autoloader was built before the class was added
  • The file case differs from the namespace (case-insensitive FS hides it locally)

Diagnosis steps

Regenerate the autoloader with verbose output

composer dump-autoload -o -vvv

Interpretation

Rebuilding the classmap reports which files were scanned and often reveals a wrong path.

Check the namespace-to-directory mapping

composer show -p | grep php && grep -n "psr-4" composer.json

Interpretation

The psr-4 block must map each namespace prefix to the directory that really holds the class file.

Confirm the file path and case

ls -l src/Service/Mailer.php

Interpretation

On Linux a filename with different case from the namespace fails; verify exact case.

Root cause

Composer resolves classes through its generated autoloader using PSR-4 prefixes. When the prefix, directory, or filename case does not match exactly, or the autoloader is stale, the class cannot be located and PHP raises a fatal not-found error.

Fix

Align the psr-4 mapping with the real directory layout, use the same case on disk as in the namespace, run composer dump-autoload -o after adding classes, and configure deployment to regenerate the autoloader.

Risk note

Running dump-autoload -o with --no-dev in production can drop dev-only classes; verify the environment flags.

Verify the fix

Reload the page or run the command that previously failed and confirm the class instantiates; check composer dump-autoload reports the class in the classmap.

Symptoms

This guide profiles the failure behind “PHP Fatal error: Class Not Found — Composer Autoload Miss”. It walks through the observable symptoms, a reproducible diagnosis path, the underlying root cause, the concrete fix, and how to verify the change and prevent a regression.

Observed symptoms include:

  • Fatal error: Uncaught Error: Class “App\Service\Mailer” not found
  • Works locally but fails on the deployed server
  • A newly added class is not found until you manually edit something

Reproduce and Diagnose

Reproduce the failure in isolation before changing any code. Work through the checks below in order; each one narrows the search space.

Step 1: Regenerate the autoloader with verbose output

composer dump-autoload -o -vvv

Rebuilding the classmap reports which files were scanned and often reveals a wrong path.

Step 2: Check the namespace-to-directory mapping

composer show -p | grep php && grep -n "psr-4" composer.json

The psr-4 block must map each namespace prefix to the directory that really holds the class file.

Step 3: Confirm the file path and case

ls -l src/Service/Mailer.php

On Linux a filename with different case from the namespace fails; verify exact case.

Likely contributors, in order of frequency:

  • The PSR-4 namespace prefix does not map to the actual directory path
  • The optimized autoloader was built before the class was added
  • The file case differs from the namespace (case-insensitive FS hides it locally)

Root Cause

Composer resolves classes through its generated autoloader using PSR-4 prefixes. When the prefix, directory, or filename case does not match exactly, or the autoloader is stale, the class cannot be located and PHP raises a fatal not-found error.

The Fix

Align the psr-4 mapping with the real directory layout, use the same case on disk as in the namespace, run composer dump-autoload -o after adding classes, and configure deployment to regenerate the autoloader.

Watch out: Running dump-autoload -o with –no-dev in production can drop dev-only classes; verify the environment flags.

{
  "autoload": {
    "psr-4": {
      "App\\": "src/"
    }
  }
}

# after adding App\Service\Mailer
composer dump-autoload -o

# production deploy
composer install --no-dev --optimize-autoloader

Verify and Prevent

Reload the page or run the command that previously failed and confirm the class instantiates; check composer dump-autoload reports the class in the classmap.

Once verified, add a regression test that reproduces the original symptom so the failure cannot silently return.

This class of failure is usually environmental rather than pure logic, so capture the exact command, the environment variables, and the working directory in your bug report. Reproduce it in the smallest possible script, then widen the scope only once the minimal case is understood. A short written checklist for this failure mode saves hours the next time it appears.