Composer is more of a dependency manager than a package manager because it only manages packages on a per-project basis. That being said, it’s almost always made my life easier when referencing other PHP libraries as well as my own. Until I did something stupid.
The problem
Earlier today, an updated build script overwrote the “vendor” folder on the remote server I was deploying to. Suddenly my app started throwing HTTP 500 errors, and I found the following in the nginx log file:
2016/03/02 12:05:24 [error] 20315#0: *104801 FastCGI sent in stderr: "PHP message: PHP Fatal error: Class 'gkn\App' not found in /srv/www/gkn.example.org/app/themes/gkn/lib/gkn/App.php on line 230" while reading response header from upstream, client: 192.168.0.1, server: gkn.example.org, request: "GET / HTTP/1.1", upstream: "fastcgi://unix:/var/run/php5-fpm-wordpress.sock:", host: "gkn.example.org"
Hmm, Composer is supposed to have created an auto-loader for this, so I simply tried to re-install my dependencies via Composer on the remote server. I typed out:
# On the remote server, in the directory where composer.json & composer.lock exist
composer install && composer update
The installation and update completed normally with no errors. But the class not found
error persisted when refreshing my web app in the browser. The problem is that Composer generates a PHP ClassLoader class to auto-load your files, and that auto-generated PHP class has a unique name. Open your vendor/autoload.php file and you’ll see an example:
<?php
// autoload.php @generated by Composer
require_once __DIR__ . '/composer' . '/autoload_real.php';
return ComposerAutoloaderInitdf2345343bf946b7c9f147fd9baa026::getLoader();
The solution
A colleague pointed out my error almost immediately via Slack, it’s obviously something he’s run up against before (thanks, Paul Frazee!) Simply put, I also needed to force a new dump of the autoload files by typing:
# SOLUTION: Force a new dump of the autoload files.
composer install && composer update && composer dump-autoload --optimize
The composer dump-autoload –optimize command regenerates your autoload files without having to run install or update. The --optimize
argument is especially important when running in your production environment for performance reasons. The optimization will speed up the time it takes for the auto-loader to load your classes, which can be relatively slow and cause your pages’ performance to suffer. It does this by converting the PSR-0/4 packages into classmap packages, which isn’t as friendly while in development, but gives you faster requests on the web server.