我正在为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-cmd
和post-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
会导致相同的错误,这让我感到很惊讶,因为我认为此时服务提供商可用。
对我来说唯一有用的是在运行config/app.php
之前手动注释掉composer update
中包含服务提供商的行,然后再添加它。我已经这样做了几个小时,它已经困扰了我,我真的不敢相信这个问题就在附近。
是否有人知道如何解决此错误,以便在更新项目的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/"
}
}
}
答案 0 :(得分:4)
此问题最终在laravel/framework:v5.2.25
和laravel/laravel:v5.2.27
之后得到解决,并被移植到laravel/framework:v5.1.33
和laravel/laravel:v5.1.33
。
除了Laravel框架(laravel/laravel
)之外,此修复还包括对Laravel应用程序(laravel/framework
)的更改。要实施,您需要:
1)更新scripts
文件的composer.json
部分,使其与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
。
在查看您在评论中发布的Github issue以及相关问题后,您可能会等待一段时间。 Taylor希望在vendor/bin
中添加一个脚本并更改composer.json
来运行该脚本,但看起来他们正在等待来自社区的PR,并且实际上并没有实现这一点。< / p>
你没有做错任何事;您的自动加载设置正确。问题出在Laravel现在。
将命令移至post-update-cmd
脚本并不起作用,因为工匠将始终尝试加载缓存文件。运行clear-compiled
命令时,artisan会在尝试删除缓存文件之前加载缓存文件(启动的一部分)。
最好的办法是在工匠运行之前手动删除缓存文件。而且,你需要在Laravel / Artisan之外做。因此,您可以手动删除文件,也可以创建一个小脚本来将其添加到composer.json
文件中(对于您的主项目,而不是您的包)。
要删除的文件:
bootstrap/cache/compiled.php
bootstrap/cache/services.php
bootstrap/cache/compiled.php
bootstrap/cache/services.json
vendor/compiled.php
storage/framework/compiled.php
vendor/services.json
storage/framework/services.json
答案 1 :(得分:1)
使用composer install
或composer update
时,您可以使用--no-scripts
选项跳过composer.json中定义的脚本的执行。
即g。:composer update --no-scripts
。
答案 2 :(得分:0)
看起来你根本就不包括你的ServiceProvider。将其放入根项目的composer.json
:
{
"autoload": {
"psr-4": {
"App\\": "app/",
"MyName\\MyProject\\": "../relative/path/to/serviceprovider/"
}
}
}
答案 3 :(得分:0)
composer update --no-scripts
此命令将忽略composer.json中定义的命令,否则将执行laravel命令,该命令将检查serviceProvider是否已加载。
答案 4 :(得分:0)
运行此
composer install --ignore-platform-reqs