Sometimes is nice to be able to access a multi-dimensional
or even a single-dimensional array with the object operator rather than clunky
array brackets.
$config->logs->event->filename;
vs
$config['logs']['event']['filename'];
This is easily done using the following class:
<?php
/**
* array_to_object.php
*
* Class for converting arrays to objects
*
* @author Paul Snell
*
*/
class ArrayToObject
{
/**
* @var array
*/
private $_arrayData = array();
/*
* ctor
* @param array $arrayData
*/
public function __construct($arrayData) {
$this->_arrayData = $arrayData;
foreach ($arrayData as $key => $data) {
if (is_array($data)) {
$this->_arrayData[$key] = new ArrayToObject($data);
}
}
}
/**
* Magic __get() method that returns corresponding value
* for a given array key
*
* @param string $name
*
* @return var
*/
public function __get($name) {
if (array_key_exists($name, $this->_arrayData)) {
return $this->_arrayData[$name];
} else {
// throw new Exception ("No entry found for array key:
" . $name);
return null;
}
}
}
?>
If you are working in an environment without in-built
support for configuration files (no framework), then you can use the previous
class in conjunction with the following one to very elegantly manage
configuration data:
<?php
require_once('array_to_object.php');
/**
*
* @author Paul Snell
*/
class LoadIni {
/**
* @var string
*/
private static $_iniData = array();
/**
* Class constructor
*
*/
private function __construct() {
}
/**
* Load up a given config file
*
* @param string
$iniFilename
* @return array $config
*/
public static function load($iniFilename, $section=null) {
if (!array_key_exists($iniFilename, self::$_iniData)) {
$base = $_SERVER['DOCUMENT_ROOT'] . '/../config/';
self::$_iniData[$iniFilename] = parse_ini_file($base . $iniFilename, true);
}
if ($section && array_key_exists($section, self::$_iniData[$iniFilename])) {
$newObj = new ArrayToObject(self::$_iniData[$iniFilename][$section]);
} else {
$newObj = new ArrayToObject(self::$_iniData[$iniFilename]);
}
return $newObj;
}
}
Note that this class is a Singleton. It is only instantiated once. Any subsequent calls for the same configuration
file will just return the existing configuration data.
However, it will create a fresh copy of the ArrayToObject()
class every time it is called. I did
that because of the option of passing in a “section” identifier. With a little effort it could probably still
be modified not to rebuild the ArrayToObject() object even then. But in the performance has never been a
significant issue, I never bothered to do it.
Using the above two classes, if you are have a configuration
file that contains something like this,
; config.ini
[amazon]
queueName =
event_transaction_queue
verifyHash = 1
minRetryTime = 60
[logs]
PrimaryLogger = /tmp/plog.log
PrimaryLoggerLevel = 5
then if we can find the minRetryTime quite easily via the
following function calls:
$config = LoadIni::load('config.ini');
$amazonRetry = $config->amazon->minRetryTime;
We can also do the following:
We can also do the following:
$config = LoadIni::load('config.ini');
$amazon = $config->amazon;
$retryTime = $amazon->minRetryTime;
$queueName = $amazon->queueName;
$retryTime = $amazon->minRetryTime;
$queueName = $amazon->queueName;
For a big project sans framework, this produces a more
elegant and manageable solution than trying to use defines in a .php
configuration file.