Php config file best practice

I tend to use a Settings static class in PHP, this is because

  • It has a global scope.
  • You can enable/disable changes to protected configs.
  • You can add any settings during anywhere within runtime.
  • You can make the class automated to fetch public configs from a file/database.

Example:

abstract class Settings
{
    static private $protected = array(); // For DB / passwords etc
    static private $public = array(); // For all public strings such as meta stuff for site

    public static function getProtected($key)
    {
        return isset(self::$protected[$key]) ? self::$protected[$key] : false;
    }

    public static function getPublic($key)
    {
        return isset(self::$public[$key]) ? self::$public[$key] : false;
    }

    public static function setProtected($key,$value)
    {
        self::$protected[$key] = $value;
    }

    public static function setPublic($key,$value)
    {
        self::$public[$key] = $value;
    }

    public function __get($key)
    {//$this->key // returns public->key
        return isset(self::$public[$key]) ? self::$public[$key] : false;
    }

    public function __isset($key)
    {
        return isset(self::$public[$key]);
    }
}

Then within your runtime, if you loaded this file first, followed by your database config file, your database config file would look like so:

<?php
Settings::setProtected('db_hostname', 'localhost');
Settings::setProtected('db_username', 'root');
Settings::setProtected('db_password', '');
Settings::setProtected('db_database', 'root');
Settings::setProtected('db_charset', 'UTF-8');
//...
echo Settings::getProtected('db_hostname'); // localhost
//...
Settings::setPublic('config_site_title', 'MySiteTitle');
Settings::setPublic('config_site_charset', 'UTF-8');
Settings::setPublic('config_site_root', 'http://localhost/dev/');

As you can see the we have a method __get that should only be allowed to grab public variables, An example of why we have this is as follows:

$template = new Template();
$template->assign('settings', new Settings());

Regardless the fact that we have used this object as a static object, the values should still stand so within the template you can now do, lets say.

<html>
    <head>
        <?php echo isset($settings->config_site_title) ? $settings->config_site_title : 'Fallback Title'; ?>
    </head>
</html>

And this will only allow you to have access to the public data during the initialized period.

This can get a lot more complex but more system friendly, some examples:

  • A loadConfig method to automatically parse a config file, xml, php, yaml.
  • If you register an shutdown_function you can auto update the database with new settings.
  • You can auto-populate the class with config from that database.
  • You can implement iterators to make it compatible with looping.
  • Lots more.

This too me is by far the best methods to complete this job.

There are different configurations for any decent web application. Some of them has to be stored on the file system, because at the initialization time you don't have access to the Data Storage, unless you hard-code it inside the source code.

You can store those configuration which are mostly database connection and encoding settings into any format that could be later feed into your application.

An INI file is good because it is simple. So if a non-technical user has to go and manually edit the configuration, it is less likely that they broke it, however there is a very small overhead in terms of parsing it. The INI files are one of the most common way of storing configuration data.

Another option is to make use of JSON to store the data. In this case it will harder to modify the file manually, however JSON is kinda established as an standard way of dealing with data. That meant to be like this in fact.

A PHP file containing any form of valid PHP code could be another option. You can define your options as Constants then you will have all of them in the global scope -- it could be a good thing at development time or a potential security hole in the production, specially if you're allowing third-party code to be included by user in your application.

A PHP Array of settings or a Serialized string of an array are other options. You can have an instance of your configuration class as well, inside your configuration file, that could provide you with extra functionality as well.

After your application is initialized, then you can connect to the data storage and load or store the rest of work in there which is more convenient for most cases.

P.S. There are dozens of other formats like XML, etc. that you can use them as a way to store the application configuration, but they are almost same as JSON and INI files in terms of explanation, so I'm not going to list all of them. You should eventually choOse a format that is more suitable for your end-user or offer them couple of ways and let them choose how they want to store the configuration -- I know that it sounds like an overkill but at some projects it's necessary to support different formats.