View Source

<ac:macro ac:name="unmigrated-inline-wiki-markup"><ac:plain-text-body><![CDATA[{zone-template-instance:ZFDEV:Zend Proposal Zone Template}

{zone-data:component-name}
Zend_Config
{zone-data}

{zone-data:proposer-list}
[Rob Allen|mailto:rob@akrabat.com]
{zone-data}

{zone-data:revision}
3.0 - 21 May 2006: Further reworking based on mailing list.
{zone-data}

{zone-data:overview}
Zend_Config is a very simple configuration file reader. It provides an easy means to read configuration files and access the data within them as a set of key-value pairs. It will support at least one nested level of data. Initially providing support for ini files, it should be easy to extend for other formats such as YAML.
{zone-data}

{zone-data:references}Mailing list thread resurrected here:

* http://www.zend.com/lists/fw-general/200604/msg00178.html. Unfortunately, I could not find the original post by Andi Gutmans in the archives.

* Other discussion can be found here: http://www.akrabat.com/index.php?s=Akrabat_Config

* Feedback on v1 from Zend is discussed here: http://www.zend.com/lists/fw-general/200605/msg00134.html

* Prototype code can be found here: http://www.akrabat.com/2006/05/13/zend_config-proposal-v2/

* Mailing list feedback on v2 is discussed here: http://www.zend.com/lists/fw-general/200605/msg00563.html

* Mailing list discussion on v2.1 is here: http://www.zend.com/lists/fw-general/200605/msg00748.html
{zone-data}

{zone-data:requirements}
* Ability to load configuration information from a single config file and provide access to the data as object properties.
* A top level section name must be specified for loading.
* Optional option to allow modification of the config data held in memory.
* No ability to modify the original data in the config file.
* For ini files, support for "namespaces" using the syntax: {{namespace.property = value}}
* Iterator is implemented for easily listing of configuration information.
* The special inheritance keyword "{{extends}}" will be used to allow for including additional sections within this section. For ini files, the syntax would be: {{extends = section}}
{zone-data}

{zone-data:dependencies}
* Zend_Exception
{zone-data}

{zone-data:operation}
Zend_Config loads and provides a property based interface to an array. The data are read only unless {{$allowModifications}} is set to {{true}} on construction. Zend_Config also implements Countable and Iterator to facilitate easy access to the data.

Sometimes it is necessary to get at a group of config variables as an array (e.g., the {{$config parameter}} in {{Zend_Db::factory()}}). Zend_Config provides the function "{{asArray()}}" to allow easy integration with such requirements.

Zend_Config_Ini is a class that loads ini files and creates and associative array for use by Zend_Config. It loads a single section from the specified ini file. It supports using the full stop character ("{{.}}") in a key name to provide additional nesting levels. That is, a key named "{{db.name}}" will be represented in the array as {{$data\['db'\]\['name'\]}}.

Zend_Config_ini also supports loading of keys from one section of the ini file into another section. This is done using a special keyword called "{{extends}}". It is possible for the parent section to itself extend from another section. Multiple inheritance, such that a section can extend
two or more other sections, is not permitted.

In order to make it easy to use with Zend_Config, Zend_Config_Ini has a static method, "{{load()}}", which loads the ini file and returns the array.

In the future, should there be demand for other config file types, other Zend_Config_XXX classes can be created for use by Zend_Config. The only requirement would be for such classes to be able to generate an associative array for loading into Zend_Config.
{zone-data}

{zone-data:class-list}
* Zend_Config_Exception
* Zend_Config
* Zend_Config_Ini
{zone-data}

{zone-data:use-cases}
Given the following:

{code:none|title=myapp.ini file}
[all]
namespace.property = example
db.connection = foo
db.name = bar
db.password = pwd
hostname = www.zend.com

[dev]
extends = all
db.name = local

[andi_dev]
extends = dev
hostname = andi_box
db.connection = localhost

[staging]
extends = all
hostname = dev.zend.com
{code}

Then we can do something like:

{code}
<?php
$obj = new Zend_Config(Zend_Config_Ini::load('myapp.ini', 'andi_dev'));
print $obj->hostname; // prints "andi_box"
print $obj->db->connection; // prints "localhost"
print $obj->db->name; // prints "local"
print $obj->db->password; // prints "pwd"
?>
{code}

Example use with Zend_Db:

{code:none|title=db.ini file}
[all]
db.type = pdoMssql
db.config.host = localhost
db.config.username = user
db.config.password = pwd
db.config.dbname = db
{code}

{code}
<?php
$obj = new Zend_Config(Zend_Config_Ini::load('db.ini', 'all'));
$db = Zend_Db::factory($obj->db->type, $obj->db->config->asArray());
?>
{code}
{zone-data}

{zone-data:skeletons}
{code}
class Zend_Config_Exception extends Zend_Exception {}

class Zend_Config implements Countable, Iterator
{
protected $_allowModifications;
protected $_iterationPointerValid;
protected $_data;

/**
* Zend_Config provides a property based interface to
* an array. The data are read only unless $allowModifications
* is set to true on construction.
*
* Zend_Config also implements Countable and Iterator to
* facilitate easy access to the data.
*
* @param array $array
* @param boolean $allowModifications
*/
public function __construct($array, $allowModifications = false) {}

/**
* Ensure that the key is a valid PHP property name
*
* @param string $key
* @return boolean
*/
protected function _isValidKeyName($key) {}

/**
* Magic function so that $obj->value will work.
*
* @param string $name
* @return mixed
*/
public function __get($name) {}

/**
* Only allow setting of a property if $allowModifications
* was set to true on construction. Otherwise, throw an exception.
*
* @param string $name
* @param mixed $value
*/
public function __set($name, $value) {}

/**
* Return an associative array of the stored data.
*
* @return array
*/
public function asArray() {}

/**
* Support isset() overloading on PHP 5.1
*
* @param string $name
* @return boolean
*/
protected function __isset($name) {}

/**
* Defined by Countable interface
*/
public function count() {}

/**
* Defined by Iterator interface
*/
public function current () {}
public function key () {}
public function next () {}
public function rewind () {}
public function valid () {}
}


class Zend_Config_Ini
{
/**
* Load $section from an ini file called $filename into
* an associative array.
*
* If any keys with $section are called "extends", then the section
* pointed to by the "extends" is then included into the properties.
* Note that the keys in $section will override any keys of the same
* name in the sections that have been included via "extends".
*
* If any key includes a ".", then this will act as a separator to
* create a sub-property.
*
* @param string $filename
* @param string $section
* @return array
*/
public static function load($filename, $section) {}

/**
* Helper function to process each element in the section and handle
* the "extends" inheritance keyword. Passes control to processKey()
* to handle the "dot" sub-property syntax in each key.
*
* @param array $iniArray
* @param string $section
* @param array $config
* @return array
*/
protected function _processExtends($iniArray, $section, $config) {}

/**
* Assign the key's value to the property list. Handle the "dot"
* notation for sub-properties by passing control to
* processLevelsInKey().
*
* @param array $config
* @param string $key
* @param string $value
* @return array
*/
protected function _processKey($config, $key , $value) {}

/**
* Helper function to handle the "dot" namespace syntax in the key.
* Uses "." as the separator.
*
* @param array $parent
* @param string $key
* @param string $value
* @return array
*/
protected function _processLevelsInKey($parent, $key, $value) {}

}
{code}
{zone-data}

{zone-template-instance}]]></ac:plain-text-body></ac:macro>