Настройки загрузки Laravel из базы данных

Я ищу эффективный способ загрузки настроек / конфигурации из базы данных с помощью Laravel 5. Настройки состоят из key а также value столбец, класс модели в основном выглядит так:

<?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'

В попытке улучшить это я создал собственный класс под названием Setting в пределах App\Classes каталог (а также создал для него Фасад):

<?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');

А теперь мой вопрос: это лучший способ решить эту проблему? Теперь я кеширую все настройки, когда класс создается. А затем получить значения настроек из кеша после этого.

Я начинаю понимать шаблон репозитория в L5, но я еще не там. Я думал, что это будет излишним в этом случае. Я хотел бы услышать, имеет ли смысл мой подход.

3

Решение

ИМХО, это немного перегружено. Вы можете сделать то же самое с помощью вспомогательного подхода:

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 попадание в кэш за запрос.

5

Другие решения

Вот обновленный ответ от Laravel 5.5.

Во-первых, создайте миграцию для вашего settings Таблица:

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.*') для каждого параметра в вашей базе данных, где * это ключ.

Например, вставьте / создайте следующий параметр:

Setting::create([
'key' => 'example',
'value' => 'Hello World',
]);

Теперь вы можете получить доступ config('settings.example'), который даст вам Hello World,

Обновление настроек так же просто, как и:

Setting::where('key', 'example')->update([
'value' => 'My New Value',
]);
12

ОП привел меня на путь развития этого пакет, который сохраняет значения пары ключей в таблицу настроек и использует кеш для сокращения запросов к БД. Если вы ищете свое собственное решение, не стесняйтесь взглянуть на мой код.

1

Вот как я решил это в Laravel 5.4. У меня есть таблица базы данных под названием configurations и создал модель для этого под названием 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') и т.п.

0
По вопросам рекламы [email protected]