6

I have the next INI file:

a.b.c = 1
a.b.d.e = 2

I am parsing this file using parse_ini_file. And it returns:

array(
    'a.b.c' => 1,
    'a.b.d.e' => 2
)

But I want to create a multidimensional array. My outout should be:

array(
    'a' => array(
        'b' => array(
            'c' => 1,
            'd' => array(
                'e' => 2
            )
        )
    )
)

Thank you in advance.

5 Answers 5

5

This is how I see it:

<?php

class ParseIniMulti {

    public static function parse($filename) {
        $ini_arr = parse_ini_file($filename);
        if ($ini_arr === FALSE) {
            return FALSE;
        }
        self::fix_ini_multi(&$ini_arr);
        return $ini_arr;
    }

    private static function fix_ini_multi(&$ini_arr) {
        foreach ($ini_arr AS $key => &$value) {
            if (is_array($value)) {
                self::fix_ini_multi($value);
            }
            if (strpos($key, '.') !== FALSE) {
                $key_arr = explode('.', $key);
                $last_key = array_pop($key_arr);
                $cur_elem = &$ini_arr;
                foreach ($key_arr AS $key_step) {
                    if (!isset($cur_elem[$key_step])) {
                        $cur_elem[$key_step] = array();
                    }
                    $cur_elem = &$cur_elem[$key_step];
                }
                $cur_elem[$last_key] = $value;
                unset($ini_arr[$key]);
            }
        }
    }

}


var_dump(ParseIniMulti::parse('test.ini'));
Sign up to request clarification or add additional context in comments.

Comments

4

It's actually quite simple, you only need to change the format of the array you already have by exploding it's key:

$ini_preparsed = array(
    'a.b.c' => 1,
    'a.b.d.e' => 2
);


$ini = array();
foreach($ini_preparsed as $key => $value)
{
    $p = &$ini;
    foreach(explode('.', $key) as $k)
        $p = &$p[$k];
    $p = $value;
}
unset($p);

print_r($ini);

Output:

Array
(
    [a] => Array
        (
            [b] => Array
                (
                    [c] => 1
                    [d] => Array
                        (
                            [e] => 2
                        )

                )

        )

)

See as well: String with array structure to Array.

1 Comment

I think you need to organize it into recursion
2

Have a look at the Zend_Config_Ini class. It does what you want, you can use it standalone (without the rest of Zend Framework) and as a bonus it supports section inheritance.

With the toArray method you can create an array from the config object.

1 Comment

Thank you. I have checked Zend_Config_Ini code fo using in my application)
2

Take a look at PHProp.

Similar to Zend_Config_Ini, but you can refer to a key in your config like ${key}

Comments

0

It's a my class for parsing config ini files to a multidimensional array:

class Cubique_Config {
    const SEPARATOR = '.';

    private static $_data = null;

    public static function get() {
        if (is_null(self::$_data)) {
            $commonIniFile = APP . '/config' . '/common.ini';
            $envIniFile = APP . '/config' . '/' . ENV . '.ini';
            if (!file_exists($commonIniFile)) {
                throw new Exception('\'' . $commonIniFile . '\' config file not found');
            }
            if (!file_exists($envIniFile)) {
                throw new Exception('\'' . $envIniFile . '\' config file not found');
            }
            $commonIni = parse_ini_file($commonIniFile);
            $envIni = parse_ini_file($envIniFile);
            $mergedIni = array_merge($commonIni, $envIni);
            self::$_data = array();
            foreach ($mergedIni as $rowKey => $rowValue) {
                $explodedRow = explode(self::SEPARATOR, $rowKey);
                self::$_data = array_merge_recursive(self::$_data, self::_subArray($explodedRow, $rowValue));
            }
        }
        return self::$_data;
    }

    private static function _subArray($explodedRow, $value) {
        $result = null;
        $explodedRow = array_values($explodedRow);
        if (count($explodedRow)) {
            $firstItem = $explodedRow[0];
            unset($explodedRow[0]);
            $result[$firstItem] = self::_subArray($explodedRow, $value);
        } else {
            $result = $value;
        }
        return $result;
    }
}

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.