Skip to main content

PHP Autoloading: Composer Autoloader Optimization

PHP · 19.04.2026 · 4 min read
Иллюстрация к статье «PHP автозагрузка и оптимизация Composer autoloader для production»

How PHP autoloading works

The PHP autoloader automatically includes a class file the first time that class is referenced. Without an autoloader you would have to write require by hand for every file. Composer generates the autoloader from the rules in composer.json.

Autoloading types in Composer

TypeDescriptionPerformance
PSR-4Namespaces → directoriesGood
PSR-0Deprecated standardWorse than PSR-4
classmapPre-built map of classesBest (production)
filesFiles that are always included—

Optimizing the autoloader for production

# Basic optimization — generates a classmap for all PSR-4 classes
composer dump-autoload --optimize

# With dev dependencies disabled
composer dump-autoload --optimize --no-dev

# APCu cache (the fastest)
composer dump-autoload --apcu --optimize --no-dev

APCu autoloader (maximum speed)

APCu caches class lookup results in memory. It requires the php-apcu extension:

sudo apt install php8.2-apcu

# In composer.json:
{
    "config": {
        "apcu-autoloader": true
    }
}

Autoload configuration in composer.json

{
    "autoload": {
        "psr-4": {
            "App\\": "src/",
            "Tests\\": "tests/"
        },
        "classmap": [
            "database/seeds",
            "database/factories"
        ],
        "files": [
            "src/helpers.php"
        ]
    }
}

Laravel: full optimization for production

# Optimize all caches
php artisan optimize

# What optimize does:
# php artisan config:cache
# php artisan route:cache
# php artisan view:cache
# composer dump-autoload --optimize
Result of optimizing the autoloader: instead of looking the file up on the filesystem on every request — an instant lookup in an in-memory array. The speed-up is 20–40% for applications with a large number of classes.

Verifying autoloading

# View the generated classmap
cat vendor/composer/autoload_classmap.php | head -20

# Size of the autoloader files
du -sh vendor/composer/

Common Autoloading Errors

Class not found after a deploy

PHP Fatal error:  Uncaught Error: Class "App\\Services\\PaymentService" not found in /var/www/html/public/index.php:12

The file vendor/composer/autoload_classmap.php is a static snapshot taken at the moment dump-autoload ran. If a new class was added after that and the autoloader was not regenerated, PHP simply does not know about it. The same happens if CI built the classmap on one branch and a different branch got deployed.

Failed opening required vendor/autoload.php

PHP Fatal error:  Uncaught Error: Failed opening required 'vendor/autoload.php' (include_path='.:/usr/share/php') in /var/www/html/public/index.php:3

The vendor/ folder is usually excluded from git — if composer install was not run on the server after deployment, the autoloader simply does not exist there.

When Classmap Optimization Does Not Fit

  • Active development with frequent new classes: after every new class the map has to be regenerated — forget it, and you get "Class not found" exactly like the example above.
  • An APCu cache lives in a specific worker's memory: after deploying new code it must be flushed separately, or the worker keeps looking up stale file paths.
  • Libraries that create classes dynamically at runtime (eval, a runtime class_alias) are not always captured correctly in the classmap — they fall back to ordinary PSR-4 lookup.

Verifying the Result

# Verbose output shows the number of classes in the map
composer dump-autoload --optimize -v
# Generated optimized autoload files containing 4821 classes

# Confirm a specific class is visible to the autoloader
php -r "var_dump(class_exists('App\\Services\\PaymentService'));"

If, after installing Composer and optimizing, the class is still not found, check that the namespace in the code matches the psr-4 key in composer.json letter for letter, including case: on Linux the filesystem is case-sensitive, unlike Windows, where the mistake might not show up for the developer but will surface in production.

Generation modeNeeds a rebuild after a new classWhere it fits
No flagsNo, resolves PSR-4 rules on the flyLocal development
--optimizeYes, the classmap is staticStaging, CI
--optimize --apcuYes, plus flushing APCu on deployProduction with long-running workers

The point of this table: the more aggressive the autoloader optimization, the stricter the requirement to regenerate it after every change to the class set — that is the price of speed.

In practice, pin the deploy command in a build script once and for all instead of typing it by hand every time — the human factor is reliably removed by automation, not by a developer's memory.

Also check the optimize-autoloader option right inside the config section of composer.json — then the --optimize flag is applied automatically on every composer install, and there is no need to remember it separately for each environment.

Was this article helpful?
← Back to Knowledge Base Ask Support