Zeta Components - high quality PHP components

eZ Components - Configuration

Introduction

The Configuration component allows you to read settings from configuration files. Those settings can come from any backend in theory, but currently there are two reader classes: ezcConfigurationIniReader for reading plain configuration files and ezcConfigurationArrayReader for reading parsed configuration files in the form of a PHP array.

The Configuration component also allows you to modify settings in configuration files and write those changes back to disk. There are two writer classes: ezcConfigurationIniWriter for writing plain configuration files and ezcConfigurationArrayWriter for writing parsed configuration files in the form of a PHP array.

The format for the plain configuration files can be found in the section File format.

Class overview

ezcConfigurationManager
This is the main class. It is responsible for calling the configured backends to read configuration data and return the settings to the application. It implements the singleton pattern and can be used in most situations where no special handling of configuration data is required.
ezcConfigurationIniReader and ezcConfigurationArrayReader
Both classes inherit from ezcConfigurationFileReader and provide lower-level access to reading configuration files. They also provide a method for validating configuration files.
ezcConfigurationIniWriter and ezcConfigurationArrayWriter
These classes write configuration files in formats that ezcConfigurationIniReader and ezcConfigurationArrayReader support.
ezcConfiguration
This is the basic class to query and modify configuration settings. Objects of this class are returned by ezcConfigurationFileReader::getConfig() and can be stored in files through the ezcConfigurationFileWriter::setConfig() method.

Basic usage

There are two basic ways to use Configuration. The first is through the manager class ezcConfigurationManager. This is suitable for most applications for retrieving configuration settings.

The second way is through the individual reader and writer classes themselves. They provide you with more finegrained control over the settings.

Using the manager

In this first example you see how configuration settings stored in the file "settings.ini" are accessed:

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. $cfg ezcConfigurationManager::getInstance();
  4. $cfg->init'ezcConfigurationIniReader'dirname__FILE__ ) . '/examples' );
  5. $pw $cfg->getSetting'settings''db''password' );
  6. echo "The password is '{$pw}'.\n";
  7. $settings $cfg->getSettings'settings''db', array( 'user''password' ) );
  8. echo "Connecting with {$settings['user']}:{$settings['password']}.\n";
  9. list( $user$pass ) = $cfg->getSettingsAsList'settings''db', array( 'user''password' ) );
  10. echo "Connecting with {$user}:{$pass}.\n";
  11. ?>

In line 4 and 5 we retrieve an instance of the ezcConfigurationManager class and initialize the system with the init() method. The two arguments specify which reader to use (ezcConfigurationIniReader) and where to find the configuration information. The second argument is the location, and its meaning is dependent on the reader class.

In line 7 we retrieve the setting "password" from the settings group "db" in the configuration named "settings". With ezcConfigurationIniReader and ezcConfigurationArrayReader, the name of the configuration corresponds to a specific file on disk.

Lines 10-11 and 13-14 show two different ways to receive a list of settings. The first method returns an associative array, while the second method returns a numerical indexed array that you can use with, for example, the list() construct.

To return a setting, there is the ezcConfigurationManager::getSetting() method and a number of additional methods. These alternative methods also check whether the type of setting is correct. See, for example, the ezcConfigurationManager::fetchArraySetting() description in the API documentation.

The ezcConfigurationManager::hasSetting() method can be used to find out whether a specific setting exists and the ezcConfigurationManager::hasSettings() method verifies whether all of the settings in a specific list exist. It is recommended to use these methods to see if a setting or list of settings exists before accessing them with one of the get*Setting() methods. This will prevent errors and exceptions.

Using the reader classes directly

Instead of using the manager class, you can also retrieve the configuration data directly with the reader classes. The following example illustrates this:

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. $reader = new ezcConfigurationIniReader();
  4. $reader->initdirname__FILE__ ), 'settings' );
  5. // validate the settings file, and loop over all the validation errors and
  6. // warnings
  7. $result $reader->validate();
  8. foreach ( $result->getResultList() as $resultItem )
  9. {
  10.     print $resultItem->file ":" $resultItem->line ":" $resultItem->column":";
  11.     print " " $resultItem->details "\n";
  12. }
  13. // load the settings into an ezcConfiguration object
  14. $cfg $reader->load();
  15. ?>

In line 4, we instantiate an object of the ezcConfigurationIniReader class and initialize it in line 5. It is also possible to initialize the reader directly through the constructor but in that case you need to specify the full file name to the configuration file. In this example, you could simply change the classname to ezcConfigurationArrayReader, for example. Lines 7 to 12 show how to use the validate() method to find out if your configuration file in in the correct format. Line 14 retrieves the settings from the configuration file and returns them as an ezcConfiguration object. You can then read and modify the settings. (See the API documentation of ezcConfiguration for the corresponding methods).

Writing configuration files

After modifying an ezcConfiguration object with the designated methods, there are multiple classes to write the configuration object back to disk. In the next example, we write an ezcConfiguration object stored in the variable $cfg to disk:

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. $writer = new ezcConfigurationArrayWriter();
  4. $writer->initdirname__FILE__ ), "settings"$cfg );
  5. $writer->save();
  6. ?>

In line 4 we instantiate the writer object, using ezcConfigurationArrayWriter to write the configuration data as a PHP structure. The component also provides a ezcConfigurationIniWriter class that writes a file that ezcConfigurationIniReader can read. After initializing the object in line 5, we use the save() method in line 6 to write the configuration file.

File format

General information regarding configuration data

The configuration format consists of four elements:

Group and setting identifiers can only contain the characters a to z, A to Z, 0 to 9, underscore (_), dash (-) and dot (.). The case of settings are preserved, but accessing them can be done with any case. This means that you cannot have two identical settings identifiers that differ only in case.

The following are legal names:

ASimpleName asimplename a_simple_name a.simple.name a-simple_and.longName

The following are illegal names:

A simple name -=A simple name=-

In addition, the group names may contain forward slashes (/), for instance:

a/simple/groupname

Ini file format

This is the format that is written by the ezcConfigurationIniWriter class and read by the ezcConfigurationIniReader class. The parser itself is located in the ezcConfigurationIniParser class.

The parser will remove leading and trailing whitespace from group names, settings and setting values. If you wish to keep whitespace in a string, it will have to be quoted.

Comments are written using a # (hash) and must be placed at the start of the line. The whitespace block before the comment text on all the lines will be trimmed away while whitespace after this block is kept. Trailing whitespace is also trimmed. For instance, the follow comments:

# A simple comment # A simple comment # A simple comment

will become:

#A simple comment # A simple comment # A simple comment

Multiple comment lines will be read as one comment with multiple lines. If there are empty lines in between comments, they will be read as empty lines in the comment itself:

# A single line comment Setting = value # Multiple lines # for this # comment Setting = value # Multiple lines # with empty lines # for this comment Setting = value # Multiple lines # # with empty lines # for this comment # Actually same as above Setting = value

Comments are always placed in front of the group or setting. A line that only contains whitespace will be ignored.

Files are always encoded in UTF-8 format, meaning that they can contain Unicode characters or plain ASCII without specific encoding.

Groups are defined by placing an identifier inside square brackets. Any setting that is read after this will be placed as part of this group. Settings without groups are not allowed and will cause an error to be issued. The group name will have its leading and trailing whitespace trimmed away:

[Group1] [Another group] [ Yet another group ]

Settings are defined by placing an identifier followed by an equal sign (=), finally followed by the value. The setting identifier and corresponding value must be on the same line, and cannot span multiple lines:

Setting1 = Some example string Setting2 = 42

The values of settings are generally strings, with the exception of:

  1. Booleans, which can be written as true or false. If you need a string that contains the text true or false it must be quoted:

    SystemEnabled = true LogErrors = false
  2. Numbers, which are written using English locale and can be in the following formats:

  1. An explicit string, which is enclosed in double quotes ("). All whitespace is kept inside the quotes and characters are read literally with the exception of escaped characters. The escaped characters are:

In addition, it is possible to define arrays in a second way by using square brackets ([]) after the setting name and before the equal (=) character. This will make the setting an array and the value is parsed as explained above. In addition, the square brackets may be enclosed around a string, turning the array into a hash (or associative array) with the text being used as the key.

List[] = First string List[] = Second string List[] = 5 Hash[abc] = 4 Hash["def"] = 5

Array file format

The Array format can be written using the ezcConfigurationArrayWriter class and read with the ezcConfigurationArrayReader class. The format is a simple var_export of the contained settings, which will be parsed for reading by PHP. The file contains an array with two elements: one for the groups and settings and one for the comments. The file could be as follows:

  1. <?php
  2. return array (
  3.   'settings' => 
  4.   array (
  5.     'site' => 
  6.     array (
  7.       'title' => 'Example site',
  8.     ),
  9.     'db' => 
  10.     array (
  11.       'host' => 'localhost',
  12.       'user' => 'root',
  13.       'password' => 42,
  14.       'connection_retries' => 'five',
  15.     ),
  16.   ),
  17.   'comments' => 
  18.   array (
  19.     'site' => 
  20.     array (
  21.       '#' => ' Settings for the site itself',
  22.     ),
  23.     'db' => 
  24.     array (
  25.       '#' => ' Database settings used for all connections',
  26.       'password' => ' Storing passwords in INI files is not a good idea,
  27.  is it?',
  28.     ),
  29.   ),
  30. );
  31. ?>

The # element in line 25 contains the comment for the group 'db' (line 23).

Lazy initialization

Lazy initialization is a mechanism to load and configure a component, only when it is really used in your application. This mechanism saves time for parsing the classes and configuration, when the component is not used at all during one request. You can find a description how you can use it for your own components and how it works in the ezcBase tutorial. The keyword for the configuration component is ezcInitConfigurationManager.

  1. <?php
  2. require_once 'tutorial_autoload.php';
  3. class customLazyConfigurationConfiguration implements ezcBaseConfigurationInitializer
  4. {
  5.     public static function configureObject$cfg )
  6.     {
  7.         $cfg->init'ezcConfigurationIniReader'dirname__FILE__ ) . '/examples' );
  8.     }
  9. }
  10. ezcBaseInit::setCallback
  11.     'ezcInitConfigurationManager'
  12.     'customLazyConfigurationConfiguration'
  13. );
  14. // Classes loaded and configured on first request
  15. $cfg ezcConfigurationManager::getInstance();
  16. $pw $cfg->getSetting'settings''db''password' );
  17. echo "The password is '{$pw}'.\n";
  18. ?>

This example shows reading the database password like the first example in this chapter. The main difference is, that we roll out the configuration to an own class, and define a callback using ezcBaseInit::setCallback to this class, which will be called with the configuration manager instance on the first request for a yet uninitialized configuration manager.

ezcBaseInit::setCallback accepts as a first parameter a component specific key, which lets the component later request the right configuration callback. The second parameter is the name of the class to perform the static callback on. This class must implement the ezcBaseConfigurationInitializer class. Each component's lazy initialization calls the static method configureObject() on the referenced class.

When the configuration manager is really required in the application, like shown in line 19 of the example, the configuration manager creates a new instance, checks if a configuration callback is provided, and uses the custom class to configure itself.