Italo Baeza Cabrera


Laravel: Loading the settings from the database (or file)

Because not everything can go to a .env file

Image for post
Image for post
“close-up photography of black metal gears” by Isis França on Unsplash

For any project, an .env file is preferred over anything else. But this file is referred as “The Environment” for the whole application. When an app must be configurable by the end user, it’s better to hold the configuration in other parts of the Application, like on the database.

Okay, you may argue that using a static file located somewhere (and editing that instead) could be better for storing the application settings than the database, leaving this for the real data itself. SQLite could help here if you don’t want to tamper with your main database, knowing current benchmarks of SQLite are not that kick in the balls against other RDBMS.

For this example I will stick to the “same Database” solution, which is quite simple.

Settings? What settings?

Let’s say in our Podcast webapp we need to pull out a settings list about if we want to show a global alert in the site, for example, to warn about a maintenance time, a new show, etc.

We need to add a settings with the warn text. If the text is empty, then no warning will be shown, since there is no point in showing an empty alert.

For that reason I will create an Eloquent Model called “Setting”, with a migration, and then I will add columns “name” and “value”, the latter being nullable.

php artisan make:model Setting --migration

After adding the columns in the migration file, I will add the settings that I want. In this case, the global alert. I did it inside one of my Database Seeders:

Setting::create([ ‘name’ => ‘global_alert’, ‘value’ => null ]);

Quite straightforward. Now, the magic.

Adding the settings to the global config

Laravel includes a handy function called config(), which holds a class with a lot of settings so every Service that your application boots, like Cache, Database, etc. can pull its own configuration data.

The neat thing about this function is that it works as a getter if you only input a string with dot notation or absolutely nothing, and as a setter if you input an array.

So, we are going to open AppServiceProvider and tell Laravel that, when the App boots, which is after all other Services are already registered, we are gonna add to the config array our own settings.

* Bootstrap any application services.
@return void
public function boot()
'global' => Setting:all([
->keyBy('name') // key every setting by its name
->transform(function ($setting) {
return $setting->value // return only the value
->toArray() // make it an array
// ...

Then the config will be added to the list, something you can check by dd(config()) after the boot method or anywhere.

That’s basically it. Of course, you could:

  • Use the DB facade directly to avoid the Eloquent Model overhead (unless you are storing arrays or json, which you will have to convert them manually, I’m sure).
  • Add a column named “group” which will allow you to group sub-settings using, and then use groupBy after retrieving all the items. Or play with dot notation.
  • Use SQLite with just using the “connection” property of the Eloquent Model or the “connection” method when using DB facade directly.
  • Make your own ServiceProvider to load the configs to be part of the booting process of your application.
  • Add a boolean column telling if it’s global, and query only those who are true, leaving the rest for later.

You can do a lot to put your own settings here inside the config. Or you can use the Fluent class for more advanced (and time-saving) things.

Bonus: Adding the warning

In your hypothetically present HomeController, I will check if the alert exists and if it’s empty before passing it to the view.

* Show the application dashboard.
* @return \Illuminate\Http\Response
public function index()
$globalAlert = config('settings.global_alert');
return view('home', [
'globalAlert' => $globalAlert

Then in some place high up the <body> I will add an if clause. PHP considers null as false, so if there is even a tiny dot on the value, it will considered as true.

<div class="alert alert-info small">
{{ $globalAlert }}

That’s pretty much it. Any other way, just it the comments.

Written by

Graphic Designer graduate. Full Stack Web Developer. Retired Tech & Gaming Editor.

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store