parse_ini_file_ex()

ちょっと正規表現使いすぎかも・・もう少し簡単にできるかもしれない。

function parse_ini_file_ex($file){
    if (!$lines = file($file, 1))
        return false;

    $res  = array();
    $curr = & $res;

    $sectionPattern  = '/^\[([^\]]+)\]/';
    // キーに記号を使いたい場合は[[:alnum:]]を[^=;]等に変更
    $linePattern     = '/^\s*([[alnum]]*)\s*=\s*(.*?)\s*$/';
    $valuePattern    = '/^"(.*?)"\s*(?:;.*)?$/';
    $commentPattern  = '/^([^;]*?)\s*;/';

    foreach ($lines as $line){
        $line = trim($line);
        if (strlen($line) === 0)
            continue;

        if (preg_match($sectionPattern, $line, $m)){
            // セクションの判断
            $res[$m[1]] = array();
            $curr = & $res[$m[1]];

        }elseif(preg_match($linePattern, $line, $m)){
            // キーと値の解析
            $key   = $m[1];
            $value = $m[2];
            if ($value{0} === '"'){
                if (preg_match($valuePattern, $value, $m))
                    $value = $m[1];
            }
            elseif(preg_match($commentPattern, $value, $m))
                $value = $m[1];

            $curr[$key] = $value;
        }
   }

    return $res;
}
$ cat temp.ini
[section]
key1 = var space
key2 = "value; 1" ; comment
key3 = "value 2 "
key4 = "value ;" value" ; comment
key5 = value1 value2 ; comment
key6 = "value ; comment

[section value]
key1 = 日本語 ; comment

$ php test.php
Array
(
    [section] => Array
        (
            [key1] => var space
            [key2] => value; 1
            [key3] => value 2
            [key4] => value ;" value
            [key5] => value1 value2
            [key6] => "value ; comment
        )

    [section value] => Array
        (
            [key1] => 日本語
        )

)