Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - Application config file stored as - ini,php,sql,cached,php class,JSON,php array?

I am trying to decide on the best way to store my applications configuration settings. There are so many options.

The majority of applications I have seen have used a simple require and a PHP file that contains variables. There seem to be far more advanced techniques out there.

What have you used? What is most efficient? What is most secure?

like image 785
Mark Avatar asked Nov 27 '09 15:11

Mark


7 Answers

We use a file called Local.php which is excluded from the SCM system. It contains several constants or global variables. For example:

// Local.php
class Setting
{
   const URL = 'http://www.foo.com';
   const DB_User = 'websmith';
}

And it can be referred to anywhere simply by:

Setting::URL

If you need the settings to be writable at runtime, I suggest you use public static variables instead.

like image 193
gahooa Avatar answered Oct 12 '22 23:10

gahooa


The best thing you can do is the simplest thing that could possibly work (php variables) and wrap it up in a class. That way you can change the implementation later without changing any client code. Create an interface that the configuration class implements and make the client code use the interface methods. If you later decide to store configuration in a database or JSON or whatever, you can simply swap out the existing implementation with a new one. Make sure your configuration class is testable and write unit tests.

like image 20
Asaph Avatar answered Oct 12 '22 23:10

Asaph


Try to use php-arrays config files using technique described here: http://www.dasprids.de/blog/2009/05/08/writing-powerful-and-easy-config-files-with-php-arrays

This method allows you to write app configuration in this way: app.config.php

<?php

return array(
  'appname' => 'My Application Name',
  'database' => array(
    'type' => 'mysql',
    'host' => 'localhost',
    'user' => 'root',
    'pass' => 'none',
    'db' => 'mydb',
  ),
);

This method is secure, cache-able by opcode cachers (APC, XCACHE).

like image 31
Sergey Kuznetsov Avatar answered Oct 13 '22 00:10

Sergey Kuznetsov


I find Zend_Config to be a good solution. You can load the configuration from a simple array, from an INI style file, or from an XML document. Whichever you choose, the configuration object is the same, so you can switch storage formats freely. Zend_Config objects can also be merged, depending on your application this may be useful (a server config, then a per site/installation config).

As with most (or all) things in the Zend Framework, you can easily use Zend_Config by itself.

Considering efficiency, I'd say the fastest method would be to use an array, since that requires less (in this case no) string parsing. However, a INI/XML format may be easier for some to maintain. Of course some caching would give you the best of both worlds.

Also, using INI files with Zend_Config allow you to define sections of configurations that inherit from each other. The most common use is a 'development' section that inherits from the 'production' section, then redefines the DB/debugging settings.

As for security, keeping the config file out of the web root is the first step. Making it read only and limiting access could make it more secure; however, depending on your hosting/server configuration you may be limited in what can be done there.

like image 33
Tim Lytle Avatar answered Oct 12 '22 22:10

Tim Lytle


How about:

; <?php die('Direct access not allowed ;') ?>
; The above is for security, do not remove

[database]
name = testing
host = localhost
user = root
pass = 

[soap]
enableCache = 1
cacheTtl = 30

Save as config.php (or something like that, must have php extention), and then just load it with:

parse_ini_file('config.php', true);

And you could use

array_merge_recursive(parse_ini_file('config-default.php', true), parse_ini_file('config.php', true))

to merge a default config file with a more specific config file.

The point here is that you can use the very readable ini format, but still be able to have your config file in a public directory. When you open the file with your browser, php will parse it first and give you the result, which will just be "; Direct access not allowed ;". When you parse the file directly as an ini file, the php die statement will be commented out according to the ini syntax (;) so it will not have any effect then.

like image 35
xyking Avatar answered Oct 12 '22 23:10

xyking


Just an example of how to implement a central XML/Xpath configuration.

class Config {
    private static $_singleton;
    private $xml;
    static function getInstance() {
        if(is_null (self::$_singleton) ) {
                self::$_singleton = new self;
        }
        return self::$_singleton;
    } 
    function open($xml_file) {
        $this->xml = simplexml_load_file($xml_file);
        return $this;
    }
    public function getConfig($path=null) {
        if (!is_object($this->xml)) {
            return false;
        }
        if (!$path) {
            return $this->xml;
        }
        $xml = $this->xml->xpath($path);
        if (is_array($xml)) {
            if (count($xml) == 1) {
                return (string)$xml[0];
            }
            if (count($xml) == 0) {
                return false;
            }
        }
        return $xml;
    }
}

Example call

Config::getInstance()
    ->open('settings.xml')
    ->getConfig('/settings/module/section/item');
like image 25
Peter Lindqvist Avatar answered Oct 13 '22 00:10

Peter Lindqvist


In my view good solution would be ini files.

I don't prefer config file using arrays/variables for storing settings; here is why:

What if a user accidently re-named your setting variable?
What if a variable with similar name is defined elsewhere too by the user?
Variables in config file may be overwritten some where deep in the script or even included files.
and possibly more problems....

I like to use ini file for setting of my php apps. Here is why:

It is section based
It is easier
You can set values by friendly names
You don't have to worry about variables being overwritten because there are no ones.
No conflict of variables of course. It allows more flexibility in specifying the types of values.

Note: You need to use parse_ini_file function to read ini files.

like image 33
Sarfraz Avatar answered Oct 13 '22 00:10

Sarfraz