Lately, I’ve been trying to tighten up my PHP coding practices. I already had a naming convention and a commenting convention defined, but the one thing I was missing was a practical, consistant, and elegant way to manage script configuration variables.

Previously, I had just been using a file called config.inc.php to hold variables like this:

$db_userName = 'chris';
$db_password = 'password';
$db_hostName = 'localhost';

The problem with this is scope. Configuration information should be global, but the “global” keyword in PHP doesn’t work as you’d think. Instead of making the variable available in any scope, it’s actually used inside a function to allow access to a variable defined in the global space.

$foo = 'bar';
 
function myFunc(){
    global $foo;
    echo $foo;
}

In the above example, the word ‘bar’ is printed to the screen. If the keyword “global” is omitted, then an empty string is printed to the screen.

This means that if you want to use 3 configuration variables in a function you need to use the “global” keyword for each to indicate to PHP that you want to use the global versions. What if you needed 20 variables…pain in the ass.

So, to solve this, I decided to use a singleton pattern to store configuration variables in an object. A singleton pattern is a way of restricting a class to one instance of itself. In this case, there is no need to have more than one object holding configuration data.

My configuration class looks like this:

class Config{
	// Member variables
 
	// Stores the only allowable instance of this class.
	static private $instanceConfig = null;
 
	// Database
	public $host = 'localhost';
	public $user = 'chris';
	public $password = 'password';
	public $database = 'my_database';
 
	public $foo = 'something';
	public $bar = 'something else';
 
	/**
	* __construct()
	*	Description: 
	*		Object constructor.  The visibility of this 
	*		function is set to private because it 
	*		should not be explicitly instantiated. This 
	*		is a singleton pattern, and must be            
	*		instantiated implicitly through the 
	*		get_instance() function.
	*	Parameters:
	*		none
	*	Returns:
	*		void
	**/
	private function __construct(){
	    // Some code goes here.
	}
 
	/**
	* get_instance
	*	Description:
	*		This function is used to instantiate the object 
	* 		and ensure only one of this type exists at any 
	*		time. It returns a reference to the only Config 
	*		instance.
	*	Parameters:
	*		none
	*	Returns:
	*		Config
	**/
	static public function get_instance(){
		/* If there is not already an instance of this class, 
		   instantiate one.*/
		if (self::$instanceConfig == null){
			self::$instanceConfig = new Config;
		}
 
		return self::$instanceConfig;
	}
}

Now, if I need a configuration variable in any function, I just do this:

function myFunc(){
	$c = Config::get_instance();
 
	echo $c->foo;
}

It seems like a complicated way to manage config variables, but if you have a really large project, it can simplify things greatly.

I spent a lot of time searching to see how other people handled this problem, but I found virtually nothing aside from the PEAR project’s configuration class, so I hope this will help others wanting the same thing.

The singleton pattern works well as a database wrapper, too, but that’s another article.