Ffile2fix
Sign in Get started

Fix "Class not found" in PHP

PHP Fatal error:  Uncaught Error: Class "App\Http\Controllers\UserController" not found in /var/www/app/routes/web.php:12

PHP tried to use a class that was never loaded. In modern projects this almost always means Composer's autoloader cannot map the class name to a file, because of a namespace or filename mismatch, a missing package, or a stale autoload cache. Built-in classes like PDO or Redis point to a missing PHP extension instead.

Also appears as: Fatal error: Uncaught Error: Class 'PDO' not found · Class "Redis" not found · Uncaught Error: Class "Composer\InstalledVersions" not found · Target class [App\Http\Controllers\HomeController] does not exist.

Common causes

  • vendor/autoload.php is not required, or the vendor folder was not uploaded or installed
  • The namespace declaration or file path does not match the PSR-4 mapping in composer.json
  • Filename case differs from the class name, which works on Windows/macOS but fails on Linux
  • The autoload cache is stale after adding or moving classes
  • A missing use statement, so PHP looks for the class in the current namespace
  • A PHP extension that provides the class (pdo_mysql, redis, intl, zip) is not installed

How to fix it

  1. Regenerate the autoloader. Run composer dump-autoload (or composer dump-autoload -o in production). If vendor is missing entirely, run composer install --no-dev.
  2. Check namespace, path and case. With "App\\": "app/" in composer.json, the class App\Http\Controllers\UserController must live in app/Http/Controllers/UserController.php with exactly that capitalization and declare namespace App\Http\Controllers;.
  3. Add the use statement. Inside a namespaced file, add use App\Models\User; at the top, or reference the class with a leading backslash such as \DateTime. Without it PHP looks in the current namespace.
  4. Install the package. If the class comes from a library, run composer require vendor/package and commit both composer.json and composer.lock so other environments install it too.
  5. Install the extension for built-in classes. For PDO, Redis, IntlDateFormatter or ZipArchive, install the extension (for example sudo apt install php8.3-mysql php8.3-redis) and restart PHP-FPM. Confirm with php -m.
  6. Clear framework caches. In Laravel run php artisan optimize:clear; in Symfony run php bin/console cache:clear. Cached route or container files can still reference renamed classes.

composer.json PSR-4 mapping

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

// app/Http/Controllers/UserController.php
<?php
namespace App\Http\Controllers;

class UserController {}

// then run: composer dump-autoload

How to stop it happening again

  • Run composer install as part of every deployment instead of copying vendor by hand
  • Develop on a case-sensitive filesystem or run CI on Linux
  • Declare required extensions such as ext-pdo or ext-redis in composer.json
  • Rename classes with an IDE refactor so the filename and namespace stay in sync

Frequently asked questions

Why does it work locally but not on the server?

Usually filename case: Windows and macOS ignore it, Linux does not. A stale or missing vendor folder on the server is the next most common cause.

Why does PHP 8 show the class name in double quotes?

PHP 8.0 changed the message format from Class 'Name' not found to Class "Name" not found. Both mean the same thing.

What does 'Target class does not exist' mean in Laravel?

It is Laravel's version of the same problem, raised by the service container. Check the controller's namespace and the full class name used in your routes, then run composer dump-autoload.