I need to dump my autoloader every time I add a new class. I am using psr-4. I don't really know why I need to do so. In psr-4 it should automatically load the classes. Where am I going wrong?
Here's my composer.json file
{"autoload": {"psr-4": {"MyDomain\\": "app"}}}
Here's my directory structure:
Here's the code for one of my classes:
<?php
namespace MyDomain\Model;
class Employee {
}
?>
PSR-4 (and also PSR-0) requires that the class ClassName
is stored in a file named ClassName.php
. The names are case sensitive and they must match exactly.
The file names in your project are lowercase, the class names are mixed case. The default disk formats on Windows and macOS are case-insensitive on search. This means when a program searches for Employee.php
and the file employee.php
exists in the directory, the search succeeds and the OS returns the existing file even if the case of its name is not the same as the case of the required file. On Linux-based OSes, the default disk format is case sensitive and a program that searches for Employee.php
cannot find employee.php
.
Your composer.json
file declares the app/
directory as the root directory of the MyDomain
namespace that follows the PSR-4
standard. This is enough for the autoloader to find the file app/Models/Employee.php
when it needs to load the class MyDomain\Models\Employee
.
Because you run it on Ubuntu (which is a Linux-based OS), PHP cannot load the Employee.php
file (because it doesn't exist) and the OS doesn't provide it the file employee.php
instead.
It seems that you generate the autoloader using composer update -o
or composer dump-autoload -o
. The -o
(short of --classmap-authoritative
) tells Composer to scan the directories declared in composer.json
(app/
) in your case and create a classmap that contains all the classes it can find. A classmap is a list that maps the classnames (with the namespace) to filenames (with directories). This way, the autoloader knows exactly where to find each class and the loading goes faster.
The above two paragraphs explain why you need to regenerate the autoloader after you add a new class.
The correct way to do the job is to follow the PSR-4
requirements. To be more specific, each namespace under MyDomain
must be stored in a subdirectory of app/
that has the same name, including the case. Each class must be stored in the correct subdirectory, in a file that has the same name as the class (including the case) and the termination .php
(lowercase). For example, the class MyDomain\Models\Employee
must stay in the file app/Models/Employee.php
.
After you fix the file names you can run composer dump-autoload
and forget about it. As long as the class and file names follow PSR-4 the autoloader will find them without regenerating it again.
On the production server you can run composer dump-autoload -o
to improve its speed a little. Just don't forget to run it again after each deploy (or, even better, include the command in the deployment script).
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With