[扩展推荐] 全局应用设置
大多数应用程序通常有必要存储一些全局设置。这些设置与特定模型(如用户模型)无关,但与整个系统有关。当然你可以通过 Eloquent 模型获得同样的效果,但我觉得这是非常糟糕的做法,因为你在关系型系统存储非关系型的数据。我发现 Spatie's Valuestore package 包非常适合为应用程序创建一个设置存储库。
这个包将会获取你的设置并在本地文件系统以 JSON 文件的形式存储它们。让我们以在应用程序顶部放置横幅通知为例。横幅通知在每一页可见并且管理员可以更新其包含的文本。
开始编码前你需要安装这个包。
composer require spatie/valuestore
现在,你可以通过指定一个要存储配置信息的文件路径来创建 Valuestore
。我想将配置文件存储在 storage/app/settings.json
文件里面,因此,我在控制器中使用静态方法 Valuestore::make($path)
实例化一个 Valuestore
,然后就可以将一些值存入其中了。
public function update(Request $request)
{
$settings = Valuestore::make(storage_path('app/settings.json'));
$settings->put('banner_notification', $request->banner_notification);
return redirect()->back()->with(['notice' => 'Settings updated']);
}
在上面的代码中,我们将 Request
中传入的 banner_notification
值存入 Valuestore
实例。Valustore
包会将存入的值进行 json 编码之后存到 settings.json
文件里面。如果这个文件不存在,它会自动创建(需要写入权限);当我们删除了这个实例的所有值时,它也会自动删除这个文件。
你在使用 Valuestore
的时候会觉得非熟悉,因为它的很多 API 与 Laravel 的 Cache
库是一样的。
你现在可以在应用的其他位置访问这些设置。为此,你只需要使用我们之前指定的文件路径来实例化 Valuestore
。
// The controller...
public function __invoke()
{
$settings = Valuestore::make(storage_path('app/settings.json'));
return view('homepage', ['settings' => $settings]);
}
// The view...
@if($settings->has('banner_notification'))
<div class="banner-notification">
{{ $settings->get('banner_notification') }}
</div>
@endif
Valuestore
是一种非常友好的方案来存储一些不需要持久化到数据库的松散值。不需要迁移,也不需要模型,只需要一个存储数据的JSON文件,这非常适合存储一些 Key => Value
的数据。只需确保将 JSON
文件存放在无法公开访问的位置即可。
该软件包还有一堆非常方便的方法 来处理持久数据,你可以点击这里 去了解一下。
了解以上内容你就可以开始使用 Valuestore
了,不过下面的内容可以帮助你更好的运用它来完成工作。
绑定到容器
在前面的例子,我们可以看到必须多次创建 Valuestore,并且在多个地方重写实例化逻辑,所以,为什么我们不将设置绑定到容器,以便我们在一个地方实例化特定的逻辑。这也将使我们可以将 Valuestore 注入到控制器中。
首先我们要创建继承自 Valuestore 的 Settings
类。
<?php
namespace App;
use Spatie\Valuestore\Valuestore;
class Settings extends Valuestore
{
//
}
接下来我们希望将 Settings
的实例绑定到容器,来作为一个服务提供者中的单例。
// AppServiceProvider...
public function register()
{
$this->app->singleton(Settings::class, function () {
return Settings::make(storage_path('app/settings.json'));
});
}
现在我们可以将设置注入具有依赖注入的控制器中。
public function update(Request $request, Settings $settings)
{
$settings->put('banner_notification', $request->banner_notification);
return redirect()->back()->with(['notice' => 'Settings updated']);
}
全局 helper 函数
当我们想在视图中读取应用配置时,添加一个全局的 settings()
helper 函数是非常方便的。尽管你可以通过 view composers
或者上面提到的在控制器里来实现这一点,但是使用全局的 helper 函数是一种更简单的方案。
// helpers.php
function settings($key = null, $default = null) {
if ($key === null) {
return app(App\Settings::class);
}
return app(App\Settings::class)->get($key, $default);
}
现在,你可以在视图里面使用全局的 helper 函数来读取应用配置了。在页面上需要添加横幅或者通知之类的设置时,这样做会非常方便。
// The view...
<div class="banner-notification">
{{ settings()->get('banner_notification') }}
{{-- or --}}
{{ settings('banner_notification') }}
</div>
这个软件包可以很方便地存储一些松散的配置项,我非常喜欢这个特性。我一直觉得将这种键值对的数据存储在数据库中不是一个很好的选择。如果你也需要在程序中操作一些全局的应用配置,我强烈推荐你使用一下 Spatie 的 Valuestore
包 。感谢 Spatie!
本文中的所有译文仅用于学习和交流目的,转载请务必注明文章译者、出处、和本文链接
我们的翻译工作遵照 CC 协议,如果我们的工作有侵犯到您的权益,请及时联系我们。