Преобразование массива в файл .ini

Мне нужно проанализировать файл .ini в массиве, а затем изменить значения массива и экспортировать его в тот же файл .ini . Мне удалось прочитать файл, но не нашел простого способа записать его. Какие-либо предложения?

Пример файла .ini :

 1 = 0; 2 = 1372240157; // timestamp. 

Чтобы записать файл .ini , вам нужно создать свою собственную функцию, поскольку PHP не предлагает никаких функций вне поля, кроме чтения (который можно найти здесь: http://php.net/manual/pl/ function.parse-ini-file.php ).

Пример функции, которая может инкапсулировать многомерный массив в .ini -syntax-совместимую строку, может выглядеть так:

 function arr2ini(array $a, array $parent = array()) { $out = ''; foreach ($a as $k => $v) { if (is_array($v)) { //subsection case //merge all the sections into one array... $sec = array_merge((array) $parent, (array) $k); //add section information to the output $out .= '[' . join('.', $sec) . ']' . PHP_EOL; //recursively traverse deeper $out .= arr2ini($v, $sec); } else { //plain key->value case $out .= "$k=$v" . PHP_EOL; } } return $out; } 

Вы можете проверить это следующим образом:

 $x = [ 'section1' => [ 'key1' => 'value1', 'key2' => 'value2', 'subsection' => [ 'subkey' => 'subvalue', 'further' => ['a' => 5], 'further2' => ['b' => -5]]]]; echo arr2ini($x); 

(Обратите внимание, что синтаксис коротких массивов доступен только с PHP 5.4+.)

Также обратите внимание, что он не сохраняет комментарии , которые присутствовали в вашем вопросе. Невозможно запомнить их, когда это программное обеспечение (в отличие от человека), которое обновляет файл.

Я внесла существенные изменения в функцию, предоставленную rr- (большое спасибо за удар!)

Я был недоволен тем, как многомерные свойства обрабатываются в этой версии. Я взял пример ini-файла со страницы документации php для parse_ini_file и получил результат, который включал ключи third_section.phpversion и third_section.urls – не то, что я ожидал.

Я попытался использовать рекурсивный атрибут для неограниченного вложенности, но, к сожалению, заголовок с парами ключ-значение под ним является максимальным пределом рекурсии, который parse_ini_string будет обрабатывать до того, как задохнется сообщение об ошибке.

Итак, я начал с нуля, добавил несколько кривых в качестве четвертого и последнего предметов, и в итоге получилось:

 $test = array( 'first_section' => array( 'one' => 1, 'five' => 5, 'animal' => "Dodo bird", ), 'second_section' => array( 'path' => "/usr/local/bin", 'URL' => "http://www.example.com/username", ), 'third_section' => array( 'phpversion' => array(5.0, 5.1, 5.2, 5.3), 'urls' => array( 'svn' => "http://svn.php.net", 'git' => "http://git.php.net", ), ), 'fourth_section' => array( 7.0, 7.1, 7.2, 7.3, ), 'last_item' => 23, ); echo '<pre>'; print_r($test); echo '<hr>'; $ini = build_ini_string($test); echo $ini; echo '<hr>'; print_r( parse_ini_string($ini, true) ); function build_ini_string(array $a) { $out = ''; $sectionless = ''; foreach($a as $rootkey => $rootvalue){ if(is_array($rootvalue)){ // find out if the root-level item is an indexed or associative array $indexed_root = array_keys($rootvalue) == range(0, count($rootvalue) - 1); // associative arrays at the root level have a section heading if(!$indexed_root) $out .= PHP_EOL."[$rootkey]".PHP_EOL; // loop through items under a section heading foreach($rootvalue as $key => $value){ if(is_array($value)){ // indexed arrays under a section heading will have their key omitted $indexed_item = array_keys($value) == range(0, count($value) - 1); foreach($value as $subkey=>$subvalue){ // omit subkey for indexed arrays if($indexed_item) $subkey = ""; // add this line under the section heading $out .= "{$key}[$subkey] = $subvalue" . PHP_EOL; } }else{ if($indexed_root){ // root level indexed array becomes sectionless $sectionless .= "{$rootkey}[] = $value" . PHP_EOL; }else{ // plain values within root level sections $out .= "$key = $value" . PHP_EOL; } } } }else{ // root level sectionless values $sectionless .= "$rootkey = $rootvalue" . PHP_EOL; } } return $sectionless.$out; } 

Мои входные и выходные массивы соответствуют (функционально, так или иначе), и мой ini-файл выглядит так:

 fourth_section[] = 7 fourth_section[] = 7.1 fourth_section[] = 7.2 fourth_section[] = 7.3 last_item = 23 [first_section] one = 1 five = 5 animal = Dodo bird [second_section] path = /usr/local/bin URL = http://www.example.com/username [third_section] phpversion[] = 5 phpversion[] = 5.1 phpversion[] = 5.2 phpversion[] = 5.3 urls[svn] = http://svn.php.net urls[git] = http://git.php.net 

Я знаю, что это может быть немного переполнено, но мне действительно нужна эта функция в двух моих проектах. Теперь я могу прочитать файл ini, внести изменения и сохранить его.

Ответ RR работает, и я добавил одно изменение

в выражении else

 //plain key->value case $out .= "$k=$v" . PHP_EOL; 

измените его на

 //plain key->value case $out .= "$k=\"$v\"" . PHP_EOL; 

Имея «вокруг значения, вы можете иметь большие значения в INI, иначе функции parse_ini_ * будут иметь проблему

http://missioncriticallabs.com/blog/2009/08/double-quotation-marks-in-php-ini-files/

Как насчет использования внутренних функций php? http://php.net/manual/en/function.parse-ini-file.php

Вы можете использовать сериализацию и записать результирующую строку в файле. Когда вы захотите снова использовать его, file_get_contents () и unserialze () вернут вам массив