I have already tried searching for this question and seen a couple of answers, but no luck…
I have composer installed with Slim Framework v3.
I am using autoload for my files using PSR-4 in the composer.json file like this:
"autoload": { "psr-4": { "App\": "App" } }
And this is my folder structure:
I am running it on a localhost Mac OS X El-Capitan using Apache 2.4 and everything works like magic. But when I upload it to my Production Linux server (also with Apache 2.4), the autoload seems to be extremely confused and I am getting errors like these:
Warning: include(/home/friendsapp/public_html/vendor/composer/../../app/Middleware/AuthMiddleware.php): failed to open stream: No such file or directory in /home/friendsapp/public_html/vendor/composer/ClassLoader.php on line 412
Warning: include(): Failed opening ‘/home/friendsapp/public_html/vendor/composer/../../app/Middleware/AuthMiddleware.php’ for inclusion (include_path=’.:/usr/lib/php:/usr/local/lib/php’) in /home/friendsapp/public_html/vendor/composer/ClassLoader.php on line 412
Fatal error: Class ‘AppMiddlewareAuthMiddleware’ not found in /home/friendsapp/public_html/public/index.php on line 5
I have namespaced my classes exactly according to my folder structure.
<?php namespace AppMiddleware; use PsrHttpMessageServerRequestInterface as Request; use PsrHttpMessageResponseInterface as Response; use AppMiddlewareMiddleware; use AppShareErrorCode; use AppModelsResultMessage; use AppMappersAccessTokenMapper; class AuthMiddleware extends Middleware {
Any help would be most appreciated! 🙂
Advertisement
Answer
Looking at the path in the errors /app/Middleware/AuthMiddleware.php
It appears the issue is caused by a namespace conflict of App\
being pointed to /app
in your production environment as opposed to your PSR-4 declaration pointing to /App
.
To avoid conflicts and map all of the namespaces of a specified directory you can use the autoload classmap
or config optimize-autoloader
(optional) options in composer.json
in order to define the physical path of all the files and objects in the specified directories for composer to load. Additionally with the PSR-4 declaration, any files not found in the classmap paths will be attempted to be loaded from the App
namespace path declaration(s). For example when using the exclude-from-classmap
option.
"config": { "optimize-autoloader": true }, "autoload": { "psr-4": { "App\": "App/" }, "classmap": [ "App/", ], }
After making the change in your composer.json
, be sure to run php composer.phar update --lock
in your development environment.
Then after uploading the composer.lock
and composer.json
files to your production environment, run php composer.phar install --no-dev -o
or php composer.phar dump-autoload --no-dev -o
from the production environment.
The -o
option will force the optimize-autoloader
classmapping to run and --no-dev
will prevent the development packages (require-dev
) from being installed. Using optimize-autoloader
is recommended for production environments.
As a general practice, anytime you deploy your development changes to your production environment you need to run php composer.phar install --no-dev -o
See How to deploy correctly when using Composer’s develop / production switch?. This way the changes applied from your development environment using php composer.phar update
are installed in your production environment correctly.