更新作曲家依赖项时 Artisan 命令出错


Error on Artisan commands when updating Composer dependencies

我正在为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

在问这个问题之前,我已经谷歌了很多,并通读了我能找到的几乎所有相关内容。显然,这是一个已知问题,已在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/"
        }
    }
}

Edit

这个问题终于在laravel/framework:v5.2.25laravel/laravel:v5.2.27得到解决,并向后移植到laravel/framework:v5.1.33laravel/laravel:v5.1.33

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

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

  • 删除"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


源语言

在查看了您在评论中发布的Github问题以及相关问题之后,您可能需要等待一段时间。Taylor 想在 vendor/bin 中放置一个脚本并更改composer.json来运行它,但看起来他们正在等待社区的 PR,并且不会自己实际实现它。

您没有做错任何事;您的自动加载设置正确。问题现在出在拉拉维尔身上。

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

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

要删除的文件:

  • 拉维尔 5.2:

    bootstrap/cache/compiled.php bootstrap/cache/services.php
  • 拉维尔 5.1:

    bootstrap/cache/compiled.php bootstrap/cache/services.json
  • 拉维尔 5.0:

    vendor/compiled.php
    storage/framework/compiled.php
    vendor/services.json storage/framework/services.json

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

例如:composer update --no-scripts .

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

composer update --no-scripts

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

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

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

运行这个

composer install --ignore-platform-reqs