I am working on a personal framework and I have been trying to move all of my configuration variables into one central file and read them from there.

I created a config class that traverses a large array, but I feel as I add more configurations to the application, its performance won't be sufficient. I am wondering if there is a better way to accomplish this.

class config {

	private static $config = null;
	private static $delimiter = '->';

	private static function &load( $path ) {
		if ( is_null( self::$config ) ) {
			self::$config = include(dirname(__FILE__).'/'.CONFIG_DIR);
		}
		if ( !is_array( $path ) ) {
			$path = explode( self::$delimiter,$path );
		}
		$array =& self::$config;
		$i = 0;
		while( $i < count( $path ) ) {
			if ( $i !== ( count( $path ) - 1 ) ) {
				$array =& $array[$path[$i]];
			}
			elseif ( $i == ( count( $path ) - 1 ) ) {
				return $array[$path[$i]];
			}
			$i++;
		}
	}

	private static function removeNull( $data ) {
		if ( is_array( $data ) ) {
			$array = array();
			foreach( $data as $key => $val ) {
				if ( is_array( $val ) ) {
					$array[$key] = self::removeNull( $val );
				}
				elseif ( !is_null( $val ) ) {
					$array[$key] = $val;
				}
			}
			return $array;
		}
		elseif ( !is_null( $data ) ) {
			return $data;
		}
	}

	public static function get( $path ) {
		return self::removeNull( self::load( $path ) );
	}

	public static function set( $path,$data ) {
		$value =& self::load( $path );
		$value = $data;
	}

	public static function remove( $path ) {
		self::set( $path,null );
	}

}

There are a few parts of the code that won't make sense, so don't comment on those. Pretty much the class loads a file containing an array and traverses it, getting/setting/removing vars using a path.
ex.

$user = config::get('database->username');
//or
$templ = config::get('templates->member->edit');

Also, I hope there is a better way of removing elements from the array, instead of setting them to null. I had to do this because using unset doesn't work on a referenced variable.

Hope someone can understand my problem. If you need some testable code, I will be happy to rewrite the code to work on your server and provide a config array to test with.

Figured I would bump this since the thread has 0 replies and give it one more try. Maybe someone will take a look and have an idea.

kkeith29,

I read your code. Really a good one but it loose its significance with deletion issue. Isn't it?

Can I see your config data?

Here is the config array I am using for my current site under development.

<?php

$config = array();

#PRODUCTION SETTING
$config['production'] = false;

#GLOBAL FILES
$config['global'] = array();

#DB CREDENTIALS
$config['database']['full']['host'] = 'localhost';
$config['database']['full']['user'] = '******';
$config['database']['full']['pass'] = '********';
$config['database']['full']['name'] = '*****';
#$config['database']['limited']['host'] = 'localhost';
#$config['database']['limited']['user'] = '*******';
#$config['database']['limited']['pass'] = '*********';
#$config['database']['limited']['name'] = '***************';

#SESSION
$config['session']['name'] = 'SESSID';

#COOKIES
$config['cookie']['auth']['allow'] = true;
$config['cookie']['auth']['name'] = 'login';

#PRIVATE PATHS
$config['path']['private'] = '/home/kkeith/private/';
$config['path']['logs'] = 'logs/';
$config['path']['classes'] = 'classes/';
$config['path']['php'] = 'php/';
$config['path']['javascript'] = 'javascript/';
$config['path']['css'] = 'css/';
$config['path']['cron'] = 'cron/';
$config['path']['templates'] = 'templates/';
$config['path']['includes'] = 'includes/';

#PUBLIC PATHS
$config['path']['public']['css'] = 'style';
$config['path']['public']['javascript'] = 'script';

#CSS
$config['css']['layout'] = 'layout.css';
$config['css']['misc'] = 'misc.css';
$config['css']['menu'] = 'menu.css';
$config['css']['form'] = 'form.css';
$config['css']['confirm'] = 'confirm/confirm.css';

#JAVASCRIPT
$config['javascript']['menu'] = 'menu.js';
$config['javascript']['pwd_strength'] = 'pwd_strength.js';

#NAVIGATION
$config['menu']['main']['home'] = array('page'=>'home');
$config['menu']['main']['buy'] = array('page'=>'buy');
$config['menu']['main']['sell'] = array('page'=>'sell');
$config['menu']['main']['register'] = array('page'=>'register');
$config['menu']['main']['contact'] = array('page'=>'contact');
$config['menu']['main']['F.A.Q.'] = array('page'=>'faq');
$config['menu']['main']['about'] = array('page'=>'about');

$config['menu']['member']['home'] = array('page'=>'home');
$config['menu']['member']['buy'] = array('page'=>'buy');
$config['menu']['member']['sell'] = array('page'=>'sell');
$config['menu']['member']['contact'] = array('page'=>'contact');
$config['menu']['member']['F.A.Q.'] = array('page'=>'faq');
$config['menu']['member']['about'] = array('page'=>'about');
$config['menu']['member']['logout'] = array('page'=>'login','do'=>'logout');

#ERROR
$config['log']['php'] = 'php.log';

#URL
$config['url']['secure'] = 'https://www.box201.com/~kkeith';
$config['url']['non-secure'] = 'http://www.box201.com/~kkeith';
$config['url']['use-rewrite'] = true;

#TITLE
$config['title']['base'] = 'Buy Or Sell Your Site :: ';

#REGEX //makes sure the regular expressions are the same throughout
$config['regex']['email'] = '#^[a-z0-9.!\#$%&\'*+-/=?^_`{|}~]+@([0-9.]+|([^\s]+\.+[a-z]{2,6}))$#si';
$config['regex']['phone'] = '/^1?[ \.\-\+]?[(]?([0-9]{3})?[)]?[ \.\-\+]?[0-9]{3}[ \.\-\+]?[0-9]{4}$/';
$config['regex']['password'] = '/^.*(?=.{3,})(?=.*\d)(?=.*[a-z])(?=.*[A-Z]).*$/';
$config['regex']['url'] = '/^(http|https|ftp):\/\/(([A-Z0-9][A-Z0-9_-]*)(\.[A-Z0-9][A-Z0-9_-]*)+)(:(\d+))?\/?/i';
$config['regex']['currency']['dollar'] = '/^\$?\-?([1-9]{1}[0-9]{0,2}(\,[0-9]{3})*(\.[0-9]{0,2})?|[1-9]{1}\d*(\.[0-9]{0,2})?|0(\.[0-9]{0,2})?|(\.[0-9]{1,2})?)$/';
$config['regex']['number'] = '/^[\d\.]+$/';
$config['regex']['alpha'] = '/^[a-zA-Z]+$/';
$config['regex']['string'] = '/^[a-zA-Z\s]+$/';
$config['regex']['alphanumeric'] = '/^\w+$/';
$config['regex']['digits'] = '/^[\d]+$/';
$config['regex']['date'] = '/^(\d{2})\/(\d{2})\/(\d{4})$/';
$config['regex']['ssn'] = '^(?!000)([0-6]\d{2}|7([0-6]\d|7[012]))([ -]?)(?!00)\d\d\3(?!0000)\d{4}$';

#EMAIL
$config['email']['main'] = '*************';

#UPLOAD
$config['upload']['directory'] = 'files/';
$config['upload']['allowed'] = array('jpeg','gif','jpg','png');
$config['upload']['maxsize'] = 500000;
$config['upload']['temp'] = 'temp/';

return $config;

?>

The deletion issue isn't a big problem. I really shouldn't need to delete anything anyway. I am just adding it as a "just in case" kind of ordeal.

Split your config datafile according to their usage and also read (datafiles) them as needed.

Did that too. I didn't like having to read different files. It made the setup difficult to manage which is why I moved it into one file. Most the sites I develop aren't for me and it needs a simple config file for non-computer savvy clients to easily make changes.

This article has been dead for over six months. Start a new discussion instead.