如何在 Laravel 外部的包中使用 Laravel 外观(缓存、日志、存储)

Posted

技术标签:

【中文标题】如何在 Laravel 外部的包中使用 Laravel 外观(缓存、日志、存储)【英文标题】:How to use Laravel facades (Cache, Log, Storage) in package outside Laravel 【发布时间】:2020-01-22 20:12:22 【问题描述】:

请指出我对 Laravel、Composer、phpUnit 等所做的任何幼稚或不正确的假设。

我在 Laravel 项目中有一个名为 SpeechToTextHelper 的类,它使用如下外观:

use Cache;
use Log;
use Storage;

然后,因为我想在多个 Laravel 项目之间共享它,我将它移到一个单独的 repo 中,并通过 Composer 将它作为依赖项(进入第一个项目)。

代码似乎运行良好。

我的问题与Using Laravel Facades outside Laravel不同

我想知道的是:

    现在我还想在我的新工具仓库中为 SpeechToTextHelper 编写 PHPUnit 测试,我看到像 RuntimeException: A facade root has not been set.Error: Class 'Log' not found 这样的错误,大概是因为这个工具仓库不知道 Laravel。我想这意味着我的生产代码一直在发挥副作用。 在我的新工具存储库(我的 SpeechToTextHelper 现在所在的位置)中,我应该如何指出(可能在 composer.json 中的某个地方?)代码只有在 Laravel 的门面存在并且正确启动的情况下才能工作?

如何修复我单独的 repo 的代码,以便它的测试可以运行,并确保它只能被 Laravel 项目“需要”?

附: https://laravel.com/docs/5.7/facades 说:“在构建与 Laravel 交互的第三方包时,最好注入 Laravel 合约 (https://laravel.com/docs/5.7/contracts) [位于他们自己的 GitHub 存储库中] 而不是使用外观。” “如果你正在构建一个包,你应该强烈考虑使用契约,因为它们会更容易在包上下文中进行测试。”

但我根本看不到日志或存储的合同。

【问题讨论】:

我们可以用Log::debug 代替app('Illuminate\Support\Facades\Log')::debug 吗? @phpdroid 我得到“尚未设置外观根。”我实际上对app() 的存在方式感到困惑。我没有看到在这个副项目中定义的位置/方式。但是 Xdebug 确实显示 app() 被调用,但随后它抛出了 RuntimeException。 【参考方案1】:

我认为您正在寻找 Laravel 组件存储库

    缓存 - 这个component 展示了如何在非 Laravel 应用程序中使用 Laravel 的缓存功能。

    Log - 这个component 展示了如何在非 Laravel 应用程序中使用 Laravel 的 Log 功能。

video 展示了如何在 laravel 之外使用 eloquent,我认为这会给你更好的想法。

【讨论】:

这很有趣,感觉它在正确的轨道上,但没有回答我的任何一个问题。例如。 github.com/mattstauffer/Torch/blob/master/components/log/… 不使用 Log 外观。我不清楚$app = new \Slim\App(); 是什么意思,或者我将如何在我的PHPUnit 测试中使用它来使它们与我的Log::debug 调用一起工作。【参考方案2】:

我不肯定这是最好的方法,所以如果其他人我很乐意 会提供更好的答案。

用于生产代码

我的composer.json 仍然在“要求”部分中有这个:"laravel/framework": "5.7.*",

我打算只在 Laravel 应用程序中需要 this 工具库。我不确定确定这是制定规则的正确方法,但我的生产代码至少似乎可以正常工作。

用于测试

至于测试,似乎有必要从https://github.com/laravel/laravel/tree/2a1f3761e89df690190e9f50a6b4ac5ebb8b35a3添加这些文件:

app/Console/Kernel.php
app/Providers/AppServiceProvider.php
app/Providers/AuthServiceProvider.php
app/Providers/EventServiceProvider.php
app/Providers/RouteServiceProvider.php
bootstrap/cache/.gitignore
bootstrap/app.php
bootstrap/autoload.php
config/app.php
config/database.php
config/logging.php
config/view.php
storage/logs/laravel.log
tests/CreatesApplication.php
tests/TestCase.php

也许这些是 Laravel 准系统文件的最小集合,没有这些文件就无法运行测试。

然后我确保每个测试类都扩展了tests/TestCase.php。我调整了命名空间。

【讨论】:

以上是关于如何在 Laravel 外部的包中使用 Laravel 外观(缓存、日志、存储)的主要内容,如果未能解决你的问题,请参考以下文章

你如何从 Laravel 的包中扩展视图?

Laravel 在包中使用自定义 USER-Model

Laravel 5.4 - 如何覆盖包中定义的路由?

将迁移放在 Laravel 5.1 包中的啥位置?

PyInstaller,如何包含 pip 安装的外部包中的数据文件?

使用 Rcpp 在 R 包中添加外部库