【问题标题】:Error on Artisan commands when updating Composer dependencies更新 Composer 依赖项时 Artisan 命令出错
【发布时间】:2019-11-20 13:36:05
【问题描述】:

我正在为 Laravel 开发一个包含服务提供者的库。我已将此库添加到另一个项目的 composer.json 文件中。

“主项目”的composer.json 文件包含以下脚本。

"scripts": {
    "post-root-package-install": [
        "php -r \"copy('.env.example', '.env');\""
    ],
    "post-create-project-cmd": [
        "php artisan key:generate"
    ],
    "post-install-cmd": [
        "php artisan clear-compiled",
        "php artisan optimize"
    ],
    "pre-update-cmd": [
        "php artisan clear-compiled"
    ],
    "post-update-cmd": [
        "php artisan optimize"
    ]
},

我可以很好地包含库依赖项,除了一件事; pre-update-cmdpost-update-cmd 脚本会抛出错误,让我很头疼。运行sudo composer update 更新依赖项时,出现以下错误。

$ sudo composer update
> php artisan clear-compiled
PHP Fatal error:  Class 'MyName\MyProject\MyAwesomeServiceProvider' not found in /Users/Me/dev/MyProject/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php on line 146


  [Symfony\Component\Debug\Exception\FatalErrorException]                                              
  Class 'MyName\MyProject\MyAwesomeServiceProvider' not found  


Script php artisan clear-compiled handling the pre-update-cmd event returned with an error


  [RuntimeException]                                                                                         
  Error Output: PHP Fatal error:  Class 'MyName\MyProject\MyAwesomeServiceProvider' 
  not found in /Users/Me/dev/MyProject/vendor/laravel/framework/src/Illuminate/Foundation/ProviderRepository.php on line 146

在问这个问题之前,我已经用 Google 搜索了很多遍,并阅读了几乎所有我能找到的相关内容。显然,这是一个已知问题,已在 Laravel 存储库中的多个 GitHub 问题中讨论过。但是,即使尝试了多种方法,我也没有找到解决方法。

问题似乎在于 Artisan 命令引导 Laravel,这会导致错误,因为此时服务提供者不可用 - 或类似的东西。将clear-compiled 命令移动到post-update-cmd 会导致同样的错误,这让我有点吃惊,因为我认为此时服务提供商将可用。

唯一对我有用的是在运行composer update之前手动注释掉config/app.php中包含服务提供者的行,然后再添加它。我已经这样做了几个小时,它已经让我很烦恼,我真的不敢相信这个问题存在。

有谁知道如何解决这个错误,这样我就不会在更新我的项目的 Composer 依赖项时收到找不到我的服务提供者的错误?

编辑: 这是库的composer.json 文件。

{
    "name": "my-name/my-project",
    "type": "library",
    "authors": [
        {
            "name": "My Name",
            "email": "test@example.com"
        }
    ],
    "require": {
        "php": ">=5.5.0",
        "laravel/framework": "~5.2"
    },
    "autoload": {
        "classmap": [],
        "psr-4": {
            "MyName\\MyProject\\": "src/"
        }
    }
}

【问题讨论】:

  • 您可以显示您图书馆的composer.json 文件吗?
  • @patricus 当然,我已经用这个编辑了这个问题。
  • 谢谢。而且,为了确保您可以在vendor/my-name/my-project/src/MyAwesomeServiceProvider.php 看到您的服务提供商,其中的第一行是<?php namespace MyName\MyProject;,对吗?所有的外壳也都匹配了吗?
  • @patricus 是的,我可以确认两者,并且自动加载也设置正确。这是一个已知问题,但我还没有找到任何适合我的解决方案。 github.com/laravel/framework/issues/9678
  • 我发现的一件事是,当你在一个包上开发并且服务提供者在app.providers 中注册但作曲家不知道它时,就会发生这种情况。在这种情况下,composer dump-autoload -o 通过重新生成其路径解决了这个问题。然后composer [install|update] 将相应地工作。

标签: php laravel laravel-5


【解决方案1】:

编辑

截至laravel/framework:v5.2.25laravel/laravel:v5.2.27,此问题终于得到解决,并向后移植到laravel/framework:v5.1.33laravel/laravel:v5.1.33

除了 Laravel 框架 (laravel/framework) 之外,此修复还包括对 Laravel 应用程序 (laravel/laravel) 的更改。要实施,您需要:

1) 更新composer.json 文件的scripts 部分以匹配laravel/laravel package 中的部分。具体来说:

  • 删除 pre-update-cmd 部分
  • post-install-cmd 部分,将"php artisan clear-compiled" 替换为"Illuminate\\Foundation\\ComposerScripts::postInstall"
  • post-update-cmd 部分,将"php artisan clear-compiled" 替换为"Illuminate\\Foundation\\ComposerScripts::postUpdate"

2) 更新composer.json 后,运行composer update。如果只想更新框架,可以运行composer update laravel/framework


原创

查看您在 cmets 中发布的Github issue 以及相关问题后,您可能需要稍等片刻。 Taylor 想在 vendor/bin 中添加一个脚本并更改 composer.json 以运行该脚本,但看起来他们正在等待社区的 PR,并且实际上不会自己实现。

你没有做错任何事;您的自动加载设置正确。问题在于 Laravel。

将命令移动到 post-update-cmd 脚本不起作用,因为 artisan 总是会在缓存文件存在时尝试加载它们。运行 clear-compiled 命令时,artisan 会在尝试删除缓存文件(启动的一部分)之前加载它们。

最好的办法是在 artisan 运行之前手动删除缓存文件。而且,你需要在 Laravel/Artisan 之外进行。因此,您可以手动删除文件,或者您可以创建一个小脚本来执行此操作并将其添加到您的 composer.json 文件(用于您的主项目,而不是您的包)。

要删除的文件:

  • Laravel 5.2:
    bootstrap/cache/compiled.php
    bootstrap/cache/services.php
  • Laravel 5.1:
    bootstrap/cache/compiled.php
    bootstrap/cache/services.json
  • Laravel 5.0:
    vendor/compiled.php
    storage/framework/compiled.php
    vendor/services.json
    storage/framework/services.json

【讨论】:

  • 感谢您的出色回答。不幸的是,它不起作用。我以前玩过这些缓存文件,但通常它们不存在。事实上,我从未在cache 目录中看到文件compiled.php。我试图删除services.php,但我仍然收到找不到我的服务提供者类的错误。我不太确定这个问题与缓存有关,因为服务提供者在缓存文件中都启用了应用程序配置,所以我猜没有区别。
  • 我对 Composer 的顺序有点困惑。我不确定 Composer 在更新过程中的哪个位置删除并重新生成自动加载文件。我试图只保留 post-update-cmd 脚本,但我仍然得到错误。看起来自动加载文件是在此脚本运行后生成的,但那会很奇怪。我有点怀疑这个问题更多地与运行 Artisan 命令时没有设置自动加载有关,但我不确定。至少它似乎与缓存无关。有任何想法吗?谢谢! :-)
  • @Andy0708 当您执行composer update 时,会在运行post-update-cmd 脚本之前生成自动加载文件(shown here)。我真的没有适合您的解决方案,但您可以尝试:1)删除缓存文件,2)composer update --no-scripts,和 3)composer update
  • 感谢 Composer 的链接 - 该顺序确实最有意义。我尝试了你的建议,但不幸的是结果是一样的。我真的不知道从这里去哪里。这是 Laravel 中的一个大缺陷,我不能真正使用这个框架。必须注释掉 5 个不同文件中的 20 行代码(目前),然后在运行 composer update 之后删除这些 cmets 简直是荒谬的,而且似乎解决方案还不够完善。我真的很失望这存在于最流行的 PHP 框架中。感谢您的帮助,我很感激!
  • 是啊,听说最近修好了,真是厉害!我会尽快关注您的更新答案并通知您。谢谢! :-)
【解决方案2】:

使用composer installcomposer update 时,您可以使用--no-scripts 选项跳过composer.json 中定义的脚本的执行。

e。 g.:composer update --no-scripts.

来源:https://getcomposer.org/doc/03-cli.md#install

【讨论】:

  • 感谢您的回答。实际上我也考虑过这一点,但认为如果不更新 Laravel 的缓存,我可能会遇到一些棘手的情况。但是,我尝试了它,但结果是我收到一个找不到服务提供者类的错误。这是加载页面时的 PHP 错误; Composer 更新完成,没有任何问题。
【解决方案3】:

看起来您根本不包括您的服务提供者。把它放在你的根项目composer.json

{
    "autoload": {
        "psr-4": {
            "App\\": "app/",
            "MyName\\MyProject\\": "../relative/path/to/serviceprovider/"
        }
    }
}

【讨论】:

  • Composer 应该自动处理自动加载,对吧?除了运行 Artisan 命令时,该类加载正常,因此自动加载似乎有效。
  • @Andy0708 Composer 只会自动加载 app/ 目录中的所有内容,除非您告诉它也像我在回答中所做的那样查看其他目录。
  • 我查看了生成的vendor/composer/autoload_psr4.php,发现我的库正在正确自动加载。这是因为我已经在库的 composer.json 文件中指定了这一点,不久前我将其添加到问题中。如果我没有这样做,那么您不会自动加载它是正确的。
【解决方案4】:
composer update --no-scripts

此命令将忽略 composer.json 中定义的命令,否则它将执行 laravel 命令,该命令将检查 serviceProvider 是否已加载。

【讨论】:

  • 检查我对建议此问题的其他答案的评论。 :-)
  • @Andy0708,我再次查看了您的问题,现在我认为问题来自自动加载,否则在您评论该服务提供者并安装后不会再次出现,请检查 psr-4 和您的定义跨度>
  • @Andy0708,也许你可以在 app 文件夹下添加你的库,并给它一个正确的命名空间,如 App\CustomLibrary\--->app/CustomLibrary/ServiceProvider
  • 自动加载应该可以正常工作,否则我将无法使用库中的类运行我的项目。它运行平稳,只是在使用 Composer 更新时不运行。我希望库存储在任意目录中并包含在 Composer 中。你的建议确实可行,但这并不是我真正想要的,因为我将独立于我正在使用它的项目开发这个库。
【解决方案5】:

运行这个

composer install --ignore-platform-reqs

【讨论】:

    猜你喜欢
    • 2021-06-05
    • 2015-12-10
    • 2017-11-10
    • 2014-04-21
    • 1970-01-01
    • 1970-01-01
    • 2014-02-09
    • 2016-06-20
    • 2019-03-13
    相关资源
    最近更新 更多