Composer的类映射自动加载不能加载文件夹中的新文件

25

以下问题:我在我的composer.json文件中定义了一个类映射:

"autoload": {
    "classmap": [
        "app/controllers",
        "app/models",
        "app/helper.php"
    ]   
}

然而,当我在“controllers”或“models”文件夹中创建一个新文件时,系统不会自动加载它们,我总是需要运行composer dump-autoload命令。

这个行为是否正确?我以为Composer的自动加载器会自动监测文件夹中的新文件呢?

4个回答

30

是的,这是正确的行为。如果您希望自动加载新类,则必须使用PSR-0或PSR-4自动加载。

生成类映射需要Composer知道包含某个类的文件名。这只能通过解析目录中的整个源代码并扫描类、接口和trait定义来完成。

这通常是一项CPU和I/O密集型任务,因此只有在Composer进行安装/更新或(按需)转储自动加载程序时才会执行,而不是每次require "vendor/autoload.php";

请注意,类映射自动加载仅适用于旧的遗留代码库,这些代码库至少没有实现PSR-0。它不适用于新代码 - 除非您想在开发期间一遍又一遍地重建自动加载器。


1
请注意,classmap自动加载仅适用于未实现至少PSR-0的旧遗留代码库。这并不完全正确。请参阅dump-autoload的文档:“--optimize (-o):将PSR-0/4自动加载转换为classmap以获得更快的自动加载器。特别是在生产环境中,建议使用此选项,但运行时间可能会有点长,因此目前默认情况下不会执行。” - spekary
优化自动加载器并不等同于定义自动加载方案。如果未来的 PHP 版本在引擎级别上支持 PSR-4,Composer 可能会放弃 classmap,以便为这样的版本进行优化,但如果该 classmap 是定义自动加载的方式,则必须保留该 classmap。 - Sven

13

通过SSH进入您的服务器根目录。现在执行以下操作:

  1. 运行ls命令以列出所有文件。
  2. 您将看到composer.lock文件; 使用rm composer.lock命令删除该文件。
  3. 现在运行php composer update命令。

根据您的Linux类型,您可能需要运行php-cli composer update命令。

第3步将创建一个新的composer.lock文件,并重新加载所有类。每次添加新类时都要执行此操作。

或者:

  1. 运行composer dump-autoload命令。

0

对我来说,使用Yii 1类映射有些棘手。当我将它与许多其他库一起添加并要求它时,它似乎也无法正常工作。我不记得是否手动编辑了文件或文件权限有问题,某些缓存也可能会影响它,因为我删除了composer.lock并完全清除了vendor文件夹,但由于某种原因它没有被重新生成,但是最终安装单个库后可解决问题,首先仅安装此单个库,然后在第二步中单独添加所有其他剩余的库,一切都可以正常加载。


0

正如已经指出的那样,这是正确的行为。如果您想要自动加载新类,您必须使用 PSR-0 或 PSR-4 自动加载。

在 composer.json 中指定的 classmap autoload 类型主要用于不遵循 PSR-0 或 PSR-4 的传统项目。我最近开始在这样的项目上工作,并希望尝试在创建新类时自动运行 composer dump-autoload 命令。这实际上是有些棘手的,因为不能将所有的 composer 源代码都包含在项目中。我提出了这个方法,只是为了提醒开发人员他们需要转储 classmap:

$loader = include_once 'vendor/autoload.php';
if ( ! $loader ) {
    throw new Exception( 'vendor/autoload.php missing please run `composer install`' );
}

spl_autoload_register(
    function ( $class ) {
        if ( 'A_Common_Class_Prefix' === substr( $class, 0, 10 ) ) {
            throw new Error( 'Class "' . $class . '"" not found please run `composer dump-autoload`' );
        }
    },
    true
);

这将注册另一个自动加载器,它会在composer的自动加载器之后运行,所以任何composer找不到的类都会传递给它。如果类与前缀匹配,则会抛出异常,提醒开发者重新生成自动加载器并更新类映射。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接