Laravel 从数据库加载设置
Laravel load settings from database
我正在寻找一种使用 Laravel 5 从数据库加载 settings/configuration 的有效方法。设置由 key
和 value
列组成,模型 class 基本上如下所示:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
protected $table = 'settings';
protected $fillable = ['key', 'value'];
protected $primaryKey = 'key';
}
起初我做了一个简单的辅助函数来完成这项工作。问题是,这会导致每个页面请求多次调用。速度越来越慢。
/**
* Get the value for the given setting from the database.
*
* @param string $key
* @return string
*/
function setting($key)
{
$setting = Setting::whereKey($key)->firstOrFail();
return $setting->value;
}
// $foo = setting('foo'); returns 'bar'
为了改进这一点,我在 App\Classes
目录中创建了一个名为 Setting
的自定义 class(并为其创建了一个 Facade):
<?php
namespace App\Classes;
use Cache;
class Setting {
/**
* The array of settings
*
* @var array $settings
*/
protected $settings = [];
/**
* Instantiate the class.
*/
public function __construct()
{
$this->loadSettings();
}
/**
* Pull the settings from the database and cache them.
*
* @return void;
*/
protected function loadSettings()
{
$settings = Cache::remember('settings', 24*60, function() {
return \App\Setting::all()->toArray();
});
$this->settings = array_pluck($settings, 'value', 'key');
}
/**
* Get all settings.
*
* @return array;
*/
public function all()
{
return $this->settings;
}
/**
* Get a setting value by it's key.
* An array of keys can be given to retrieve multiple key-value pair's.
*
* @param string|array $key;
* @return string|array;
*/
public function get($key)
{
if( is_array($key) ) {
$keys = [];
foreach($key as $k) {
$keys[$k] = $this->settings[$k];
}
return $keys;
}
return $this->settings[$key];
}
}
// $foo = Setting::get('foo');
现在我的问题是:这是解决这个问题的最佳方法吗?我现在在构建 class 时缓存所有设置。然后从缓存中检索设置值。
我开始理解 L5 中的 Repository 模式,但我还没有。我认为在这种情况下这太过分了。我很想听听我的方法是否有意义。
恕我直言,这有点过度设计了。您可以使用辅助方法执行相同的操作:
function settings($key)
{
static $settings;
if(is_null($settings))
{
$settings = Cache::remember('settings', 24*60, function() {
return array_pluck(App\Setting::all()->toArray(), 'value', 'key');
});
}
return (is_array($key)) ? array_only($settings, $key) : $settings[$key];
}
不那么繁琐。没有循环。每个请求最多命中 1 个数据库。每个请求最多命中 1 次缓存。
这是我在 Laravel 5.4 中的解决方法。我有一个名为 configurations
的数据库 table 并为其创建了一个名为 Configuration
的模型。正如您提到的,configurations
有一个 key
和 value
。当然,如果需要,您可以将其更改为 Settings
。
在AppServiceProvider
boot()
中添加:
// cache configuration
Cache::forever('configuration', Configuration::all());
创建一个辅助函数(我把它放在 App\Http\helpers.php 中,它在我的作曲家自动加载中):
function configuration($key)
{
return Cache::get('configuration')->where('key', $key)->first()->value;
}
然后您可以使用 configuration('key_name')
等在任何地方访问该值
这是截至 Laravel 5.5 的更新答案。
首先,为您的 settings
table 创建迁移:
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('key');
$table->text('value')->nullable();
$table->timestamps();
});
然后创建一个Setting
模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
protected $fillable = ['key', 'value'];
}
现在,在 AppServiceProvider
中,将以下内容添加到您的 boot()
方法中:
if (Schema::hasTable('settings')) {
foreach (Setting::all() as $setting) {
Config::set('settings.'.$setting->key, $setting->value);
}
}
这将为您数据库中的每个设置创建 config('settings.*')
,其中 *
是键。
例如,insert/create以下设置:
Setting::create([
'key' => 'example',
'value' => 'Hello World',
]);
现在您可以访问 config('settings.example')
,这将为您提供 Hello World
。
更新设置非常简单:
Setting::where('key', 'example')->update([
'value' => 'My New Value',
]);
OP 引导我走上了开发这个 package, which saves key-pair values to a settings table and uses cache to reduce DB queries. If you're looking for your own solution, feel free to take a look at my code 的道路。
我的 Laravel 版本是 6.0(目前最新),我不得不搜索这个问题并找到解决方案,编译上面的所有答案让我们开始吧.
第一步:在App目录下创建Helpers.php文件
namespace App;
use Cache;
class Helpers
{
/**
* Fetch Cached settings from database
*
* @return string
*/
public static function settings($key)
{
return Cache::get('settings')->where('key', $key)->first()->value;
}
}
第 2 步:使用以下内容创建设置模型
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Settings extends Model
{
protected $fillable = ['key', 'value'];
}
步骤 3:为设置创建迁移 table 并迁移
Schema::create('settings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('key')->unique();;
$table->text('value')->nullable();
$table->timestamps();
});
第 4 步:添加到 App\Providers\ServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Cache;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Cache::forever('settings', \App\Models\Settings::all());
}
}
第 5 步:使用 tinker 或任何其他方法添加一些设置
第 6 步:用法
- 将
use App\Helpers;
添加到您的控制器
- 试试
dd(Helpers::settings('your_setting_name_here'));
优点:
- 易于访问(只需使用所需的设置名称调用您的设置方法)
- 缓存所有设置(保存数据库调用)
我正在寻找一种使用 Laravel 5 从数据库加载 settings/configuration 的有效方法。设置由 key
和 value
列组成,模型 class 基本上如下所示:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
protected $table = 'settings';
protected $fillable = ['key', 'value'];
protected $primaryKey = 'key';
}
起初我做了一个简单的辅助函数来完成这项工作。问题是,这会导致每个页面请求多次调用。速度越来越慢。
/**
* Get the value for the given setting from the database.
*
* @param string $key
* @return string
*/
function setting($key)
{
$setting = Setting::whereKey($key)->firstOrFail();
return $setting->value;
}
// $foo = setting('foo'); returns 'bar'
为了改进这一点,我在 App\Classes
目录中创建了一个名为 Setting
的自定义 class(并为其创建了一个 Facade):
<?php
namespace App\Classes;
use Cache;
class Setting {
/**
* The array of settings
*
* @var array $settings
*/
protected $settings = [];
/**
* Instantiate the class.
*/
public function __construct()
{
$this->loadSettings();
}
/**
* Pull the settings from the database and cache them.
*
* @return void;
*/
protected function loadSettings()
{
$settings = Cache::remember('settings', 24*60, function() {
return \App\Setting::all()->toArray();
});
$this->settings = array_pluck($settings, 'value', 'key');
}
/**
* Get all settings.
*
* @return array;
*/
public function all()
{
return $this->settings;
}
/**
* Get a setting value by it's key.
* An array of keys can be given to retrieve multiple key-value pair's.
*
* @param string|array $key;
* @return string|array;
*/
public function get($key)
{
if( is_array($key) ) {
$keys = [];
foreach($key as $k) {
$keys[$k] = $this->settings[$k];
}
return $keys;
}
return $this->settings[$key];
}
}
// $foo = Setting::get('foo');
现在我的问题是:这是解决这个问题的最佳方法吗?我现在在构建 class 时缓存所有设置。然后从缓存中检索设置值。
我开始理解 L5 中的 Repository 模式,但我还没有。我认为在这种情况下这太过分了。我很想听听我的方法是否有意义。
恕我直言,这有点过度设计了。您可以使用辅助方法执行相同的操作:
function settings($key)
{
static $settings;
if(is_null($settings))
{
$settings = Cache::remember('settings', 24*60, function() {
return array_pluck(App\Setting::all()->toArray(), 'value', 'key');
});
}
return (is_array($key)) ? array_only($settings, $key) : $settings[$key];
}
不那么繁琐。没有循环。每个请求最多命中 1 个数据库。每个请求最多命中 1 次缓存。
这是我在 Laravel 5.4 中的解决方法。我有一个名为 configurations
的数据库 table 并为其创建了一个名为 Configuration
的模型。正如您提到的,configurations
有一个 key
和 value
。当然,如果需要,您可以将其更改为 Settings
。
在AppServiceProvider
boot()
中添加:
// cache configuration
Cache::forever('configuration', Configuration::all());
创建一个辅助函数(我把它放在 App\Http\helpers.php 中,它在我的作曲家自动加载中):
function configuration($key)
{
return Cache::get('configuration')->where('key', $key)->first()->value;
}
然后您可以使用 configuration('key_name')
等在任何地方访问该值
这是截至 Laravel 5.5 的更新答案。
首先,为您的 settings
table 创建迁移:
Schema::create('settings', function (Blueprint $table) {
$table->increments('id');
$table->string('key');
$table->text('value')->nullable();
$table->timestamps();
});
然后创建一个Setting
模型:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
protected $fillable = ['key', 'value'];
}
现在,在 AppServiceProvider
中,将以下内容添加到您的 boot()
方法中:
if (Schema::hasTable('settings')) {
foreach (Setting::all() as $setting) {
Config::set('settings.'.$setting->key, $setting->value);
}
}
这将为您数据库中的每个设置创建 config('settings.*')
,其中 *
是键。
例如,insert/create以下设置:
Setting::create([
'key' => 'example',
'value' => 'Hello World',
]);
现在您可以访问 config('settings.example')
,这将为您提供 Hello World
。
更新设置非常简单:
Setting::where('key', 'example')->update([
'value' => 'My New Value',
]);
OP 引导我走上了开发这个 package, which saves key-pair values to a settings table and uses cache to reduce DB queries. If you're looking for your own solution, feel free to take a look at my code 的道路。
我的 Laravel 版本是 6.0(目前最新),我不得不搜索这个问题并找到解决方案,编译上面的所有答案让我们开始吧.
第一步:在App目录下创建Helpers.php文件
namespace App;
use Cache;
class Helpers
{
/**
* Fetch Cached settings from database
*
* @return string
*/
public static function settings($key)
{
return Cache::get('settings')->where('key', $key)->first()->value;
}
}
第 2 步:使用以下内容创建设置模型
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class Settings extends Model
{
protected $fillable = ['key', 'value'];
}
步骤 3:为设置创建迁移 table 并迁移
Schema::create('settings', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('key')->unique();;
$table->text('value')->nullable();
$table->timestamps();
});
第 4 步:添加到 App\Providers\ServiceProvider.php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Cache;
class AppServiceProvider extends ServiceProvider
{
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Cache::forever('settings', \App\Models\Settings::all());
}
}
第 5 步:使用 tinker 或任何其他方法添加一些设置
第 6 步:用法
- 将
use App\Helpers;
添加到您的控制器 - 试试
dd(Helpers::settings('your_setting_name_here'));
优点:
- 易于访问(只需使用所需的设置名称调用您的设置方法)
- 缓存所有设置(保存数据库调用)