Русское сообщество разработки на PHP-фреймворке Laravel.
Ты не вошёл. Вход тут.
Страницы 1
Всем привет. Сделал я две сущности SettingsServiceProvider и SettingsModel. Но возникла проблема - в момент отработки провайдера соединение с БД еще не установлено и возникает ошибка при работе с моделью. Собственно вопрос: как более грамотно вытягивать настройки из БД, желательно единожды на запрос, и желательно без какого-либо кэширования?
Не в сети
Нашел решение, которое меня устраивает. Если кому-то покажется полезным ...
Создаю модель 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, // <---------- тут
];
Ну вот и все.
Не в сети
Страницы 1