Karthik
Karthik

Reputation: 1091

Array to object

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

Answers (3)

Edson Medina
Edson Medina

Reputation: 10269

// assuming $var is a multidimensional array
$obj = json_decode (json_encode ($var), FALSE);

Upvotes: 0

hakre
hakre

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

Lake
Lake

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

Related Questions