If you find yourself in a situation where you need to store settings table in a configuration file, but in the same time you don’t want to sacrifice given the User/Admin the ability to update those settings when needed, then you’ve come to the right place.
One of the reasons you may want to store your application settings in file is avoiding hitting the database too much.
Well, I faced this problem myself in one of the projects I worked on. It was a relatively a small project. Storing my settings in a configuration file may not gain me too much in perfomance, but for my own peace of mind, I did it anyway.
Here is schema definition of settings table:
<?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')->unique();
$table->text('value');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('settings');
}
}
As you can see, it’s key => value
combination.
Well, the solution turns out to be pretty simple, all I had to do was taking adavantage of the Eloquent Model Events. To be more precise I used saved
event, because the saving
/saved
events will dispatch when a model is created or updated.
This is tested in Laravel 8 application, but I believe it will work well from Laravel version 5.5 and up.
<?php
namespace App\Models;
use Illuminate\Support\Facades\File;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class Setting extends Model
{
use HasFactory;
/**
* The attributes that aren't mass assignable.
*
* @var array
*/
protected $guarded = [];
/**
* The "booted" method of the model.
*
* @return void
*/
protected static function booted()
{
static::saved(function () {
$settings = static::pluck('value', 'key')->toArray();
$parsable_string = var_export($settings, true);
$content = "<?php return {$parsable_string};";
File::put(config_path('app_settings.php'), $content);
});
}
//...
}
Nothing complex is really going on here. First, throughout the Eloquent pluck
method we retrieve an Illuminate\Support\Collection
instance containing the keys/values.
Chaining toArray
method converts the collection into a plain PHP array
.
PHP function var_export
returns a parsable string representation of the $settings
variable.
I also use the config_path
function to generate a fully qualified path to a file within the application’s configuration directory, a file I named app_settings.php. You are free to change it to whatever suits you best.
The put
method is used to store file contents on the disk.
I did one more thing, I added /config/app_settings.php
to .gitignore
file.