每次添加新课时我都需要转储自动加载器。我正在使用psr-4。我真的不知道为什么需要这样做。在psr-4中,它应该自动加载类。我哪里错了?
这是我的composer.json文件
target=this
这是我的目录结构:
这是我的一个课程的代码:
{"autoload": {"psr-4": {"MyDomain\\": "app"}}}
答案 0 :(得分:10)
PSR-4(以及PSR-0)要求类ClassName
存储在名为ClassName.php
的文件中。名称区分大小写,并且必须完全匹配。
项目中的文件名是小写的,类名是大小写混合的。 Windows和macOS上的默认磁盘格式在搜索时不区分大小写。这意味着当程序搜索Employee.php
并且文件employee.php
存在于目录中时,搜索成功并且OS返回现有文件,即使其名称的大小写不同于所需的文件。在基于Linux的操作系统上,默认磁盘格式区分大小写,搜索Employee.php
的程序找不到employee.php
。
您的composer.json
文件将app/
目录声明为遵循MyDomain
标准的PSR-4
命名空间的根目录。这足以让自动加载器在需要加载类app/Models/Employee.php
时找到文件MyDomain\Models\Employee
。
因为你在Ubuntu(基于Linux的操作系统)上运行它,PHP无法加载Employee.php
文件(因为它不存在)并且操作系统没有提供它文件employee.php
代替。
您似乎使用composer update -o
或composer dump-autoload -o
生成自动加载器。 -o
(简称--classmap-authoritative
)告诉Composer在您的案例中扫描composer.json
(app/
)中声明的目录,并创建一个包含它可以找到的所有类的类映射。 classmap是一个列表,它将类名(带有命名空间)映射到文件名(带有目录)。通过这种方式,自动装带器可以确切地知道每个类的位置,并且加载速度更快。
以上两段解释了添加新类后需要重新生成自动加载器的原因。
正确的工作方式是遵循PSR-4
要求。更具体地说,MyDomain
下的每个命名空间必须存储在具有相同名称的app/
子目录中,包括大小写。每个类必须存储在正确的子目录中,存储在与类(包括大小写)和终止.php
(小写)同名的文件中。例如,类MyDomain\Models\Employee
必须保留在文件app/Models/Employee.php
中。
修复文件名后,您可以运行composer dump-autoload
并忘记它。只要类和文件名遵循PSR-4,自动加载器就会找到它们而不再重新生成它。
在生产服务器上,您可以运行composer dump-autoload -o
来提高速度。只是不要忘记在每次部署后再次运行它(或者更好的是,在部署脚本中包含该命令)。