Сохранение конфигурации в базе данных в Laravel - PullRequest
1 голос
/ 07 апреля 2020

Я сейчас использую Laravel 5.2. Я хочу иметь возможность хранить свойства конфигурации (пары ключ-значение) в базе данных, к которой я готов получить доступ как из моего приложения во время выполнения, так и из консоли (либо php artisan команда, либо Tinker).

Какой мой лучший вариант?

  • .env - это один способ, но он хранится не в базе данных, а в файле.
  • Config::get - это другой способ, но это также пишет в файлах. Может ли он быть настроен на запись в базу данных?
  • Cache::get настроен для работы с базой данных, но является временным, а не постоянным, поэтому об этом не может быть и речи.

Я заинтересован в настройке базы данных, потому что мы часто заменяем / удаляем файлы во время развертывания. Также было бы неплохо хранить значения в зашифрованном виде. Также важной особенностью здесь является возможность легко получать значения с помощью php artisan или tinker

.

1 Ответ

1 голос
/ 07 апреля 2020
  1. Выполнить миграцию: php artisan make:migration CreateSettingsTable
<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateSettingsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('settings', function (Blueprint $table) {
            $table->id();
            $table->string('key');
            $table->string('value');
            $table->timestamps();

            $table->unique([
                'key', //I add a unique to prevent double keys
            ]);
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('settings');
    }
}
Сделать модель: php artisan make:model Setting
<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class Setting extends Model
{
    protected $fillable = [
        'key',
        'value'
    ];

    //I would normally do this in a repository,
    // but for simplicity sake, i've put it in here :)
    static public $settings = null;

    static function get($key, $default = null)
    {
        if (empty(self::$settings)) {
            self::$settings = self::all();
        }
        $model = self
            ::$settings
            ->where('key', $key)
            ->first();
        if (empty($model)) {
            if (empty($default)) {
                //Throw an exception, you cannot resume without the setting.
                throw new \Exception('Cannot find setting: '.$key);
            }
            else {
                return $default;
            }
        }
        else {
            return $model->value;
        }
    }

    static function set(string $key, $value)
    {
        if (empty(self::$settings)) {
            self::$settings = self::all();
        }
        if (is_string($value) || is_int($value)) {
            $model = self
                ::$settings
                ->where('key', $key)
                ->first();

            if (empty($model)) {
                $model = self::create([
                    'key' => $key,
                    'value' => $value
                ]);
                self::$settings->push($model);
            }
            else {
                $model->update(compact('value'));
            }
            return true;
        }
        else {
            return false;
        }
    }
}

Обратите внимание, что я добавил функции get и set вместе с переменной stati c $settings непосредственно в модель. , чтобы сохранить пример маленьким. Обычно я бы предпочел создать репозиторий или сервис (не сервис-провайдер) для обработки этих функций. Таким образом, вы запрашиваете БД только один раз (за запрос) для всех настроек. Вы можете вставить это в кеш, но это не является частью этого ответа.

Запустите php artisan migrate, чтобы получить таблицу в БД.

Выполните composer dump-autoload, чтобы убедиться, что тинкер может найти класс Setting.

Используйте что-нибудь вроде php artisan tinker (https://laravel.com/docs/7.x/artisan#tinker), чтобы проверить его, в этом случае вы можете сделать:

Setting::set('someKey', 'someValue'); //Set someKey to someValue
Setting::get('someKey'); //Get someKey, throws exception if not found
Setting::get('somekey2', 'someDefault'); //Shows someDefault because somekey2 is not set yet.

Я надеюсь, что это помогает! :)

...