PeeHaa
PeeHaa

Reputation: 72729

Using configuration files in a PHP project

I need to have some configuration options on my website.

I thought it would be easiest to maintain if different options are placed in different files.

Also I need to have a class to retrieve the options from different configuration files.

In the directory structure of my website I created a directory called /setup

In this directory I have several files for the different configuration options, eg: /setup/base.php

The contents of base.php will look something like the following:

$setup = new stdClass();
$setup->currencies = array('USD', 'EUR', );
$setup->locations = array('local', 'international', );

I would like to create a class which reads the file and returns the different options.

class Options
{
    function __construct($option)
    {
        if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
            thrown new Exception('Configuration file not found.');
        }

        $options = // get information from file

        return $options; // this should return the currencies and locations
    }
}

$options = new Options('base');

However I don't know whether this is the correct way of doing it.

If so I cannot think of a way to retrieve the options from the setup files in the class.

Can you help me with this or at least point me in the right direction?

Upvotes: 1

Views: 816

Answers (4)

cwallenpoole
cwallenpoole

Reputation: 82088

Well, I don't think there is a right way for this one: Zend uses .ini files, Codeigniter has a set of arrays, and Symfony uses YAML. Wordpress stores most everything in the database, and has one config file which it just includes.

Personally, I'm partial to ini files -- ini is something which is used all over the place, so it has a feeling of, "I can reuse this if necessary", but I think that the only "wrong" solution here is one which is inconsistent -- if you're using ini, use ini, if arrays, arrays, but don't mix.

In your case, there are a couple of options. These two seem to be among the most common. (both of these examples assumes that the stdClass object is named $options in the loaded file) You could create a wrapper:

class Options
{
    private $_options;
    function __construct($option)
    {
        if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
            thrown new Exception('Configuration file not found.');
        }

        require(SETUP_DIR.'/'.$option.'.php');
        $this->_options = $options;
        // you shouldn't put a return in a constructor 
    }

    // this will point to the internal _options variable.
    // making it a read-only access to the values from $option
    public function __get($name){ return $this->_options->$name; }
}

Or, you could use a Singleton pattern and just return the objects in the individual classes:

class OptionsRetriever
{
    private $_fetched;
    private static $_instance;

    private __construct(){}

    public static function &getInstance()
    {
        if( !isset( self::$_instance ) ) self::$_instance = new OptionsRetriever();
        return self::$_instance;
    }

    public function getConfig( $name )
    {
        if( !isset( $this->_fetched[ $name ] ) )
        {
            require(SETUP_DIR.'/'.$name.'.php');
            $this->_fetched[ $name ] = $options;
        }
        return $this->_fetched[ $name ];
    }
}

Or, you could combine them:

class Options
{
    private $_options;
    function __construct($options)
    {
        $this->_options = $options;
    }

    public function __get($name){ return $this->_options->$name; }
}

    // replace getConfig with this
    public function getConfig( $name )
    {
        if( !isset( $this->_fetched[ $name ] ) )
        {
            require(SETUP_DIR.'/'.$name.'.php');
            $this->_fetched[ $name ] = new Options( $options );
        }
        return $this->_fetched[ $name ];
    }

Upvotes: 2

Tommy Bravo
Tommy Bravo

Reputation: 532

You could just include the base.php file, like so:

class Options
{
    function __construct($option)
    {
        if (!is_file(SETUP_DIR.'/'.$option.'.php')) {
            thrown new Exception('Configuration file not found.');
        }

        include_once(SETUP_DIR.'/'.$option.'.php');

        $options = $setup; // make sure your variable in the config is allways named $setup

        return $options; // this should return the currencies and locations
    }
}

$options = new Options('base');
echo $options->currencies[0]; //should print 'USD' provided that your base.php file from the question was used.

Upvotes: 1

Mick Hansen
Mick Hansen

Reputation: 2704

If you wan't the values stored in PHP directly you would need to include PHP files with the values in them, for instance as variables, constants or classes.

A method i like to use is storing configuration in an XML file and then loading and parsing that. Same method could be used with JSON if you prefer that format. Just make sure you block any browser access to those files.

Upvotes: 0

Jake
Jake

Reputation: 2470

You can use the concept of ini files and the parse_ini_file function in PHP to accomplish this. There are clear examples on the php.net function page: parse_ini_file @ PHP.NET

Upvotes: 1

Related Questions