Laravel по-русски

Русское сообщество разработки на PHP-фреймворке Laravel.

Ты не вошёл. Вход тут.

#1 09.02.2024 12:32:54

Majestio
Откуда: Минск
Сообщений: 23
Сайт

Хранение и доступ к настройкам

Всем привет. Сделал я две сущности SettingsServiceProvider и SettingsModel. Но возникла проблема - в момент отработки провайдера соединение с БД еще не установлено и возникает ошибка при работе с моделью. Собственно вопрос: как более грамотно вытягивать настройки из БД, желательно единожды на запрос, и желательно без какого-либо кэширования?

Не в сети

#2 09.02.2024 15:43:34

Majestio
Откуда: Минск
Сообщений: 23
Сайт

Re: Хранение и доступ к настройкам

Нашел решение, которое меня устраивает. Если кому-то покажется полезным ...

Создаю модель SettingsModel, миграцию под нее, сидер. Потом создаю middleware под названием LoadSettingsFromDatabase и регаю его глобально в app/Http/Kernel.php. Код app/Http/Middleware/LoadSettingsFromDatabase.php следующий:

<?php

namespace App\Http\Middleware;

use Closure;
use Illuminate\Http\Request;
use Symfony\Component\HttpFoundation\Response;
use App\Models\SettingsModel;

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Log;


class LoadSettingsFromDatabase
{
    /**
     * Handle an incoming request.
     *
     * @param  \Closure(\Illuminate\Http\Request): (\Symfony\Component\HttpFoundation\Response)  $next
     */
    public function handle(Request $request, Closure $next): Response
    {
        if (!Cache::has('settings')) {   
            $settings = SettingsModel::all();
            foreach ($settings as $setting) {
                config(['settings.'.$setting->key => $setting->value]);
            }
            Cache::put('settings', $settings, 5);
            Log::alert('read settings from database');
        } else {
            $settings = Cache::get('settings');
            foreach ($settings as $setting) {
                config(['settings.'.$setting->key => $setting->value]);
            }
            Log::alert('settings loaded from cache');
        }
        return $next($request);
    }
}

Для теста в шаблоне главной страницы пишу:

{{ config('settings.theme') }}

Собственно, что выводит мне bootstrap5-theme. В логах storage/logs/laravel.log наблюдаю с одного запроса:

[2024-02-09 12:03:48] local.ALERT: read settings from database  
[2024-02-09 12:03:48] local.ALERT: settings loaded from cache  
[2024-02-09 12:03:48] local.ALERT: settings loaded from cache  

app/Models/SettingsModel.php

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class SettingsModel extends Model
{
    use HasFactory;

    protected $table = 'settings';
    protected $fillable = ['key', 'value'];
}

database/migrations/2024_02_09_112339_create_settings_table.php

<?php

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

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

    /**
     * Reverse the migrations.
     */
    public function down(): void
    {
        Schema::dropIfExists('settings');
    }
};

database/seeders/SettingsSeeder.php

<?php

namespace Database\Seeders;

use Illuminate\Database\Console\Seeds\WithoutModelEvents;
use Illuminate\Database\Seeder;
use App\Models\SettingsModel;

class SettingsSeeder extends Seeder
{
    /**
     * Run the database seeds.
     */
    public function run(): void
    {
        SettingsModel::create([
            'key' => 'theme',
            'value' => 'bootstrap5-theme'
        ]);
    }
}

Ну а глобальную регу мидлваря производим в app/Http/Kernel.php, тут:

    protected $middleware = [
        // \App\Http\Middleware\TrustHosts::class,
        \App\Http\Middleware\TrustProxies::class,
        \Illuminate\Http\Middleware\HandleCors::class,
        \App\Http\Middleware\PreventRequestsDuringMaintenance::class,
        \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
        \App\Http\Middleware\TrimStrings::class,
        \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
        \App\Http\Middleware\LoadSettingsFromDatabase::class,  // <---------- тут
    ];

Ну вот и все.

Не в сети

Подвал раздела