Reputation: 1091
I wrote a custom framework. Which uses the .ini type of config file.
Say, if I have a constant assigned in the .ini file as
[production]
db.mongo.hostName = localhost
I am currently parsing this through parse_ini_file()
function.
The result will be
$config[production][db.mongo.hostname] = "localhost";
Now I wanna turn this array to an object which should go like
$config->db->mongo->hostname
I tried exploding it with '.'
, but then I am stuck with forming this as an above iterative object.
Can someone please help me with this.
Upvotes: 1
Views: 283
Reputation: 10269
// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);
Upvotes: 0
Reputation: 197554
The following is a rudimentary class that has a single function to import the ini array as you have specified it:
/**
* Config "Class"
* @link http://stackoverflow.com/q/11188563/367456
*/
class Config
{
public function __construct(array $array = array())
{
$this->importIniArray($array);
}
public function importIniArray(array $array)
{
foreach ($array as $key => $value) {
$rv = &$this;
foreach (explode('.', $key) as $pk) {
isset($rv->$pk) || $rv->$pk = new stdClass;
$rv = &$rv->$pk;
}
$rv = $value;
}
}
}
I only added the __construct
function because you re-use the variable. Usage:
$config = parse_ini_file($path);
$config = new Config($config['production']);
print_r($config);
Exemplary output:
Config Object
(
[db] => stdClass Object
(
[mongo] => stdClass Object
(
[hostname] => localhost
[user] => root
)
)
)
Edit: You can also solve the problem to locate the array member at time of access. I compiled a little example that behaves similar and it explodes nothing. I called it DynConfig
because as you'll see it's dynamic (or magic):
$config = new DynConfig($config['production']);
var_dump($config);
echo $config->db->mongo->hostname; # localhost
The var_dump
shows that the array is just preserved internally:
object(DynConfig)#1 (1) {
["array":"DynConfig":private]=>
array(2) {
["db.mongo.hostname"]=>
string(9) "localhost"
["db.mongo.user"]=>
string(4) "root"
}
}
So how does this work? Each time you access a property, either a key exists or the prefix is extended and the same object is returned. That's in the __get
function:
/**
* Config "Class"
* @link http://stackoverflow.com/q/11188563/367456
*/
class DynConfig
{
private $array;
public function __construct($array)
{
$this->array = $array;
}
public function __get($name)
{
static $prefix = '';
$k = $prefix .= $name;
if (isset($this->array[$k])) {
$prefix = '';
return $this->array[$k];
}
$prefix .= '.';
return $this;
}
}
However, this is of experimental nature. The first suggestion is much more direct and much easier to deal with. Keep in mind that your config object should be really simple, it just needs to store some values and that's it.
Upvotes: 3
Reputation: 913
You can done it as below
function assignTo($obj,$keys,$value)
{
if(count($keys) > 1)
{
$h = array_shift($keys);
$obj->$h = $obj->$h ? $obj->$h : new stdClass();
assignTo($obj->$h,$keys,$value);
}
else
{
$obj->$keys[0] = $value;
}
}
$config['production']['db.mongo.hostname'] = "localhost";
$config['production']['db.mongo.password'] = "1234567";
$config['production']['version'] = "1.0";
$object = new stdClass();
foreach($config['production'] as $key=>$value)
{
assignTo($object,explode('.',$key),$value);
}
print_r($object);
Which would output:
stdClass Object
(
[db] => stdClass Object
(
[mongo] => stdClass Object
(
[hostname] => localhost
[password] => 1234567
)
)
[version] => 1.0
)
Upvotes: 2