2

I would like to make use of somehting like [parse_ini_file][1].

Lets say for instance I have a boot.ini file that I will load for further procedure:

    ;database connection settings
[database]
type        =   mysql;
host        =   localhost;
username    =   root;
password    =   "";
dbName      =   wit;

However, I would like to have it in a different way as the php array would be:

$ini['database']['whatever']

So first of all I would like to have my boot.ini like this structure:

;database settings (comment same style)
db.host1.type = mysql;
db.host1.host = localhost;
db.host1.username = root;
db.host1.password = "";
db.host1.dbName = wit;

db.host2.type = mysql;
db.host2.host = otherHost;
db.host2.username = root;
db.host2.password = "";
db.host2.dbName = wit;

So when I now access the file I would like to access it this way:

$ini['db']['host1']['whatever']

And on top of that I would like to do it via OOP so lets say: $ini->db->host1->whatever

or `$ini->db->host1` 

will return an array with all the attributes such as type, host, username, password and the dbName;

I appreciate anykind of help. Thank you very much in advance.

  [1]: http://uk2.php.net/manual/en/function.parse-ini-file.php

3 Answers 3

4

Well, you need to postprocess the parse_ini_file result array then.

$ini_array = parse_ini_file("bootstrap.ini");

$ini = new stdclass;
foreach ($ini_array as $key=>$value) {
    $c = $ini;
    foreach (explode(".", $key) as $key) {
        if (!isset($c->$key)) {
            $c->$key = new stdclass;
        }
        $prev = $c;
        $c = $c->$key;
    }
    $prev->$key = $value;
}

Update Hackety-Hack. Now using an extra $prev to unset the last object level again. (A for loop to detect the last $key would have worked better).

If you want to use the array syntax and the object syntax, then replace the new stdclass with new ArrayObject(array(), 2);.

Sign up to request clarification or add additional context in comments.

4 Comments

Uhm, I think your is nicer, since it has fewer lines and fewer conditions. I also wanted to move $prev->$key = $value; out of loop, but in some reason decided that $last hack will be better. Well it is not, $prev is more handy in this case ;-)
Well the $prev hack pollutes the local scope with an extra variable, and creates an temporary object, then overwrites it, so it probably fragments the heap a bit more. Hencewhy the $last check is likely also quicker. -- Anyway, turned out to have more edge cases than expected.. :]
heap fragmentation is the last thing I ever think of when program using php )))
perfect, thank you very much! actually it seems very simple, as you are just working exploding the string and depending on that you continue - hmm why did I not think about that :((
3
$ini_array = parse_ini_file("sample.ini");

$ini = new stdclass;
foreach ($ini_array as $key => $value) {
    $last = substr(strrchr($key, '.'), 1);
    if (!$last) $last = $key;

    $node = $ini;

    foreach (explode('.', $key) as $key2) {
        if (!isset($node->$key2)) {
            $node->$key2 = new stdclass;
        }

        if ($key2 == $last) {
            $node->$key2 = $value;
        } else {
            $node = $node->$key2;
        }
    }

}

var_dump($ini->db->host1->type);

Comments

0

I got an elegant solution for you. This implementation allows inheritance and vectors using dots as our collegue "zerkms" showed us before. In truth, I took his solution and improved it. Thus the solution be like Zend Parser :) I tested it and works. But, as we know, is impossible test all possibilities. Then, I hope attent people detect troubles and propose corrections.

Here goes the code (as a function):

function parse($filename) {

        $ini_array = parse_ini_file ( $filename, true );

        if (! $ini_array)
            throw new Exception ( 'Error on parsing ini file!', - 1 );

        $ini = new stdClass ();

        //Parse section...
        foreach ( $ini_array as $namespace => $prop ) {

            $section = $namespace;
            $ext = explode ( ':', $namespace );

            if (count ( $ext ) == 2) {

                $section = trim ( $ext [0] );
                $extend = trim ( $ext [1] );

                if (! isset ( $ini->$extend ))
                    throw new Exception ( 'Parent section doesn\'t exists!', - 1 );

                $ini->$section = clone $ini->$extend;

            } else
                $ini->$section = new stdClass ();

            foreach ( $prop as $key => $value ) {

                $arr = explode ( '.', $key );
                $n = count ( $arr ) - 1;

                if ($n) {
                    $aux = $ini->$section;
                    for($i = 0; $i < $n; ++ $i) {

                        if(!isset($aux->$arr [$i]))
                            $aux->$arr [$i] = new stdClass ();

                        $aux = $aux->$arr [$i];
                    }
                    $aux->$arr [$n] = $value;
                } else
                    $ini->$section->$key = $value;

            }

        }

        return $ini;

}

And here goes an example of .ini file:

[environment]
env_name = production
x.y = 3

[oi : environment]
z = 5

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.