全局应用程序设置
发布日期 作者 timacdonald
在应用程序中,通常需要一种方法来存储一些全局设置。这些设置与特定模型(如用户)无关,而是与整个系统有关。当然,您可以使用 Eloquent 来实现这一点,但我从未觉得这是正确的方法,因为您是在关系型系统中保存非关系型数据。我发现 Spatie 的 Valuestore 包非常适合创建应用程序的设置存储库。
该包将获取您的设置并将其存储为本地文件系统上的 JSON 文件。让我们以在应用程序顶部显示横幅通知为例。横幅通知在每个页面上可见,管理员可以更新其包含的文本。
要开始使用,您需要安装该包。
composer require spatie/valuestore
现在,您可以通过指定要读取和写入设置的磁盘上的路径来创建一个 Valuestore。我希望我的设置文件位于 storage/app/settings.json
,因此在我的控制器中,我将使用静态 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']);}
如您在此代码片段中所见,我们将请求输入 banner_notification
添加到 Valuestore 中。在后台,Valustore 包对值进行 JSON 编码,并将它们存储在文件系统上的 settings.json
中。该包将为我们管理此文件,因此如果该文件不存在,它将创建该文件;如果我们删除所有值,它将删除该文件以进行清理。
该 API 与 Laravel 的缓存存储库共享许多相同的方法,因此使用起来应该很熟悉。
现在,您可以在应用程序的其他位置访问这些设置。为此,您需要使用之前指定的相同路径实例化 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 文件。非常适合一些基本的键值对。只需确保将您的设置文件放在无法公开访问的位置即可。
该包还有一些其他 非常有用的方法,可以用于处理您的持久化数据,您应该查看一下。
虽然这些就是您入门所需的全部内容,但我还发现以下提示在使用 Valuestore 时非常有用。
绑定到容器
在前面的示例中,您会看到我们必须多次创建 Valuestore,并且我们在多个地方重写了实例化逻辑,因此,我们为什么不将我们的设置绑定到容器,以便我们可以在一个地方指定实例化逻辑呢?这还将使我们能够将 Valuestore 注入到我们的控制器中。
首先,我们将创建自己的 Settings
类,该类扩展了 Valuestore。
<?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']);}
全局助手
我发现添加一个全局的 settings()
助手在您希望在视图中访问设置时也非常有用。虽然您可以使用视图组合器或通过控制器(如前所述)传递来实现这一点,但我发现全局助手是一种更简单的方法。
// helpers.php function settings($key = null, $default = null) { if ($key === null) { return app(App\Settings::class); } return app(App\Settings::class)->get($key, $default);}
现在,您可以在视图中通过全局助手检索设置。当某个设置(如横幅通知)需要在每个页面上显示时,这尤其有用。
// The view... <div class="banner-notification"> {{ settings()->get('banner_notification') }} {{-- or --}} {{ settings('banner_notification') }} </div>
我真的很喜欢该包带来的简单性,它使您能够存储一些松散值。我一直觉得,在数据库中使用某种键值对设置来存储此类数据从未完全正确。如果您需要一些全局可用的应用程序设置,我强烈建议您查看 Spatie 的 Valuestore 包。感谢 Spatie!