If you have a Slim website (not just using for API), what do you find is the best way to access site settings? In a previous instance of my project, I created a middleware that would get the settings from the db but that’s a lot of queries. Better way?
One idea I had was writing the settings out to a file on save.
I’m not certain if I’m following… but for my site name I’m storing that within a Twig include. So my “master” template will include another template which is just a set of variable definitions.
{% set siteName = 'My Awesome Site' %} {% set supportEmail = 'support@example.com' %}
In this manner, Twig also caches them upon first use. Is this what you mean?
hmmmm… I guess I look at those changes as changes that I do want to be under version control. Otherwise, if they are actual “settings” and thus might vary between production, staging, and dev environments… I’ll put them into my settings.php which is not under version control. I’d then load/fetch them from the container via other objects. (Like keys to external services).
Hey @shavonn - similar to what @tflight has suggested, I use a config system which is loosely based around ZF2 and the other larger frameworks. Basically, create a config folder, with *.global.php and *.local.php settings files which are then read into the application on start and accessed from the container, so can be injected anywhere in your app. Something like the following should work:
public function autoloadConfigFiles()
{
$globalConfig = [];
$localConfig = [];
$globalFiles = glob('config/autoload/*.global.php');
$localFiles = glob('config/autoload/*.local.php');
foreach ($globalFiles as $globalFile) {
$globalConfig = array_merge_recursive($globalConfig, require($globalFile));
}
if (isset($localConfig)) {
foreach ($localFiles as $localFile) {
$localConfig = array_merge_recursive($localConfig, require($localFile));
}
}
$config = array_replace_recursive($globalConfig, $localConfig);
// Set the config:
return $config;
}
That way you can overwrite global configs files (like production files etc) with local ones when you’re devving and vice versa. If you then do something like this:
// You can access the config from anywhere really
$config = $someService->autoloadConfigFiles();
/** @var \Slim\App $slimApp */
$slimApp = new \Slim\App($config);
Alternatively, you can add it to a container in your dependencies or set up, or any other way you want to, but that gives you the ability to create multiple config files for separate parts of the application etc and then inject them / access them / use them from anywhere if they are in a container.
I have a site_settings table that is loaded with one DB call into an array. i.e. The load settings method runs SQL along the lines of select key_name, value from site_settings which is reasonably quick
The load settings functionality is called from within a container factory so that it doesn’t run unless needed. i.e. the first time that the app does $container->get('site_settings')['some_setting'], the database query runs precisely once.
Most of my projects are not that large. I will have a settings.php file that I load when I instantiate Slim. I then pass the settings via Dependancy Injection to any Controller/Service that requires them.
index.php
$settings = require __DIR__ . '/../src/settings.php';
$app = new \Slim\App($settings);
The load settings functionality is called from within a container factory so that it doesn’t run unless needed. i.e. the first time that the app does $container->get(‘site_settings’)[‘some_setting’], the database query runs precisely once.
This is quite interesting. Could you share a code snipped for this? Thanks
I have created a nice little class to load this for me:
class Config
{
public static function load($directory)
{
$config = [];
$path = realpath($directory);
$items = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($path), \RecursiveIteratorIterator::SELF_FIRST);
foreach ($items as $item)
{
if (!is_dir($item))
{
$parts = pathinfo($item);
array_push($config, [$parts['filename] => require $item);
}
}
}
}
And I call it by passing the directory. An array is returned so I name my config according to what it is: app.php / db.php / etc etc. All of these return arrays