PSR-4 autoloading not working
Asked Answered
J

2

6

I have created an app/modules directory and autoloaded it using PSR-4 like this:

"psr-4": {
    "Modules\\": "app/modules"
}

And I also did composer dumpautoload. I have the following directory structure:

app
- ...
- modules
-- ModuleName
--- controllers
---- BackendController.php
...

The file BackendController.php has the namespace Modules\ModuleName\Controllers.

And in routes.php, I have the following:

Route::resource('backend/modules/module-name', 'Modules\ModuleName\Controllers\BackendController');

But whenever I try to access 'backend/modules/module-name', I get a ReflectionException with the following message:

Class Modules\ModuleName\Controllers\BackendController does not exist

What may be causing the problem? When I run it in my local machine, it seems to work, but I can't get it to work on the webserver. Are there any server configuration scenarios, that may be causing this problem?

Since I don't have shell access to that webserver, I don't have composer installed on the webserver but it is installed on my local machine. I have uploaded all the files including vendor directory, to the server.

Jessamine answered 30/6, 2014 at 17:50 Comment(1)
Try capitalizing the controllers folder to Controllers.Burgomaster
L
20

From PSR-4 specification:

All class names MUST be referenced in a case-sensitive fashion.

So you'll need to rename your modules and controllers folders to Modules and Controllers respectively.

So it becomes:

app
- ...
- Modules
-- ModuleName
--- Controllers
---- BackendController.php
...

I wouldn't recommend renaming your namespaces to lowercase names because that just breaks the consistency in your code and project structure. It will be a headache to maintain and figure out which part of your namespace needs to be capitalized which one doesn't.

Lumpen answered 30/6, 2014 at 17:59 Comment(2)
Thank you for the answer. I forgot about the case-sensitivity.Jessamine
I just realized that the spec says "class names". I have no idea if they intended to mean namespace names in the first place. But oh well, this is the closest clarification.Lumpen
S
8

You should look at capitalization.

Probably you test it on Windows machine so path

'Modules\ModuleName\Controllers\BackendController'

is the same as

'modules\ModuleName\controllers\BackendController'

But on Linux they are 2 different paths. You should probably change in your routes.php line from

Route::resource('backend/modules/module-name', 'Modules\ModuleName\Controllers\BackendController');

to

Route::resource('backend/modules/module-name', 'modules\ModuleName\controllers\BackendController');
Saxony answered 30/6, 2014 at 17:59 Comment(3)
That's what was wrong with my code and setup. I thought the autoloader would take care of that. I guess I was wrong. Thank you for the answer.Jessamine
I had the same issue but lower case paths actually worked in Linux - or SO I THOUGHT! It turned out I was testing inside a Vagrant box which mapped the paths out to my host OS X machine - which in turn uses case INsensitive filesystem. Caught it during production deploy :)Accumulation
thanks for your comment...my problem solved...what a stupid mistake.... :(Napalm

© 2022 - 2024 — McMap. All rights reserved.