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:
1 |
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:
1 2 |
# 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:
1 2 3 4 |
<?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:
1 2 |
# 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.
Have a similar issue, or found a better solution? Leave a comment below!