每次添加新的 class 时都需要转储自动加载

Need to dump autoload to everytime I add a new class

每次添加新的 class 时,我都需要转储自动加载器。我正在使用 psr-4。我真的不知道为什么我需要这样做。在 psr-4 中它应该自动加载 classes。我哪里错了?

这是我的 composer.json 文件

{"autoload": {"psr-4": {"MyDomain\": "app"}}}

这是我的目录结构:

这是我的 classes 之一的代码:

<?php

namespace MyDomain\Model;

class Employee {

}  
?>

PSR-4(以及 PSR-0)要求 class ClassName 存储在名为 ClassName.php 的文件中。名称区分大小写,并且必须完全匹配。

您项目中的文件名是小写的,class 名称是大小写混合的。 Windows 和 macOS 上的默认磁盘格式在搜索时是 case-insensitive。这意味着当程序搜索 Employee.php 并且文件 employee.php 存在于目录中时,搜索成功并且 OS returns 现有文件,即使它的名称大小写与所需文件的情况不同。在 Linux-based OSes 上,默认磁盘格式区分大小写,搜索 Employee.php 的程序找不到 employee.php.

您的 composer.json 文件将 app/ 目录声明为遵循 PSR-4 标准的 MyDomain 命名空间的根目录。这足以让自动加载器在需要加载 class MyDomain\Models\Employee.

时找到文件 app/Models/Employee.php

因为你运行它在Ubuntu(这是一个Linux-basedOS),PHP无法加载Employee.php文件(因为它不存在)并且 OS 没有向它提供文件 employee.php

您似乎使用 composer update -ocomposer dump-autoload -o 生成自动加载器。 -o--classmap-authoritative 的缩写)告诉 Composer 扫描在 composer.jsonapp/)中声明的目录,并创建一个包含所有内容的 classmap它可以找到的 classes。 classmap 是一个将 class 名称(带有命名空间)映射到文件名(带有目录)的列表。这样,自动加载器就知道在哪里可以找到每个 class 并且加载速度更快。

以上两段解释了为什么添加新的class后需要重新生成自动加载器。

正确的做法是按照PSR-4的要求。更具体地说,MyDomain 下的每个命名空间都必须存储在 app/ 的同名子目录中,包括大小写。每个 class 必须存储在正确的子目录中,在一个与 class(包括大小写)和结尾 .php(小写)同名的文件中。例如,class MyDomain\Models\Employee 必须保留在文件 app/Models/Employee.php.

修复文件名后,您可以 运行 composer dump-autoload 而忘掉它。只要 class 和文件名跟在 PSR-4 之后,自动加载器就会找到它们而无需重新生成它们。

在生产服务器上,您可以运行 composer dump-autoload -o 稍微提高它的速度。只是不要忘记在每次部署后再次 运行 它(或者,更好的是,将命令包含在部署脚本中)。