Developing software in the Real World

Akrabat_Config (2nd Attempt)

Update! This version has been superceded! Check out Akrabat_Config (Take Three!) for an even better version…

Nico Edtinger was kind enough to review Akrabat_Config and pointed out that it wouldn’t handle a key with multiple dots in it. His post to fw-general:

One method I don’t “like” is processSection(). If I have a name like “foo.bar.baz” it would be saved as $config[‘foo’][‘bar’], dropping the last part because you explode without a third parameter. It should be
$pieces = explode(‘.’, $key, 2);

I’d also change the check for a dot to
if(strpos($key, ‘.’)) {

That would work with a key with a leading dot (being stored just as is instead of $config[”][…]) and the explode doesn’t need to parse a string that doesn’t have a dot anyway and create an array that’s not needed.

Thus, this is my second attempt at Akrabat_Config:

The new tests are:

iniFilename = dirname(__FILE__).'/data/config.ini';
}

function testLoadAll()
{
Zend::loadClass('Akrabat_Config');
$config = new Akrabat_Config($this->iniFilename, 'all');
$this->assertEquals('all', $config->hostname);
$this->assertEquals('all', $config->test['me']);
}

function testInclude()
{
Zend::loadClass('Akrabat_Config');
$config = new Akrabat_Config($this->iniFilename, 'staging');
$this->assertEquals('staging', $config->hostname);
$this->assertEquals('staging', $config->test['me']);
}

function testMultiLevels()
{
Zend::loadClass('Akrabat_Config');
$config = new Akrabat_Config($this->iniFilename, 'multi');
zend::dump($config);
$this->assertEquals('four', $config->one['two.three']);
$this->assertEquals('five', $config->one['two.three.four']);
}

function testLeadingDot()
{
Zend::loadClass('Akrabat_Config');
$config = new Akrabat_Config($this->iniFilename, 'dot');
$this->assertEquals('dot', $config->get("."));
$this->assertEquals('doubledot', $config->get(".."));
$this->assertEquals('t-dot', $config->get("t."));
$this->assertEquals('dot-t', $config->get(".t"));
}
}

?>

with data/config.ini:

and Akrabat_Config looks like this:

hostname = staging
* $config->db['connection'] = database
*
*
* @param string $filename
* @param string $section
*/
function __construct($filename, $section)
{
$iniArray = parse_ini_file($filename, true);

$config = array();
if(isset($iniArray[$section]))
{
foreach($iniArray[$section] as $key => $value)
{
if($key == 'include')
{
if(isset($iniArray[$value]))
{
$config = array_merge($config, $this->processSection($iniArray[$value]));
}
unset($iniArray[$section][$key]);

}
}
$config = array_merge($config, $this->processSection($iniArray[$section]));
}
else
{
throw new Exception("No section '$section' in $filename'");
}
$this->_config = $config;
}

/**
* Helper function to handle single level namespace in the key
*
* @param array $section
* @return array
*/
protected function processSection($section)
{
$config = array();
foreach($section as $key=>$value)
{
if(strpos($key, '.'))
{
$pieces = explode('.', $key, 2);
if(!empty($pieces[1]))
{
$config[$pieces[0]][$pieces[1]] = $value;
}
else
{
$config[$key] = $value;
}
}
else
{
$config[$key] = $value;
}

}
return $config;
}

/**
* @param string $name
* @param mixed $default
* @return mixed
*/
function get($name, $default=false)
{
$result = $default;
if(isset($this->_config[$name]))
{
$result = $this->_config[$name];
}
return $result;
}

/**
* magic function so that $config->value will work.
*
* @param string $name
* @return mixed
*/
function __get($name)
{
return $this->get($name);
}

}
?>

2 thoughts on “Akrabat_Config (2nd Attempt)

  1. Looks interesting. I've always hated to have my settings all over the place. It's also something that I don't like in my bootstap file. It's clutter ;) Then again, there ini functions in PHP if i'm not mistaken, so this could be considered reinventing the wheel…

  2. Yes – this class is a thin wrapper around the ini handling function. Though it provides additional functionality by allowing for overriding of keys in one section with keys in another.

    On the fw-general list we are talking about allowing for loading multiple files into one config object. I quite like that idea so might play with it tonight.

Thoughts? Leave a reply

Your email address will not be published. Required fields are marked *