我需要将.ini
文件解析为数组,然后更改数组的值并将其导出到相同的.ini
文件。
我设法读取了该文件,但没有找到任何简单的方法来回写它。
有什么建议吗?
示例.ini
文件:
1 = 0;
2 = 1372240157; // timestamp.
答案 0 :(得分:8)
为了写回.ini
文件,你需要创建自己的函数,因为除了阅读之外,PHP不提供开箱即用的功能(可以在这里找到:http://php.net/manual/pl/function.parse-ini-file.php)
可能将多维数组封装到.ini
的函数示例 - 语法兼容字符串可能如下所示:
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以后可用。)
另请注意,它不会保留您的问题中出现的评论。当软件(而不是人类)更新文件时,没有简单的方法可以记住它们。
答案 1 :(得分:1)
我对rr-提供的功能进行了重大更改(非常感谢您的启动!)
我对在该版本中处理多维属性的方式感到不满意。我从parse_ini_file的php文档页面中获取了示例ini文件,得到的结果包括密钥third_section.phpversion
和third_section.urls
- 而不是我的预期。
我尝试使用RecursiveArrayIterator进行无限制嵌套,但不幸的是,其下面带有键值对的标头是parse_ini_string在阻塞错误消息之前将处理的最大递归限制。< / p>
所以我从头开始,添加了一些曲线球作为第四个和最后一个项目,最后得到了这个:
$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文件,进行更改并保存。
答案 2 :(得分:0)
RR的答案有效,我添加了一个更改
in else statement
//plain key->value case
$out .= "$k=$v" . PHP_EOL;
将其更改为
//plain key->value case
$out .= "$k=\"$v\"" . PHP_EOL;
通过&#34;围绕该值,您可以在INI中使用大值,否则parse_ini_ *函数将出现问题
http://missioncriticallabs.com/blog/2009/08/double-quotation-marks-in-php-ini-files/
答案 3 :(得分:0)
这是我对 rr- 的增强版回答(感谢他),我的函数是 laravel 生态系统中 class 的一部分,所以函数名为 Arr::isAssoc 主要用于检测给定数组是否为关联数组。
private function arrayToConfig(array $array, array $parent = []): string
{
$returnValue = '';
foreach ($array as $key => $value)
{
if (is_array($value)) // Subsection case
{
// Merge all the sections into one array
if (is_int($key)) $key++;
$subSection = array_merge($parent, (array)$key);
// Add section information to the output
if (Arr::isAssoc($value))
{
if (count($subSection) > 1) $returnValue .= PHP_EOL;
$returnValue .= '[' . implode(':', $subSection) . ']' . PHP_EOL;
}
// Recursively traverse deeper
$returnValue .= $this->arrayToConfig($value, $subSection);
$returnValue .= PHP_EOL;
}
elseif (isset($value)) $returnValue .= "$key=" . (is_bool($value) ? var_export($value, true) : $value) . PHP_EOL; // Plain key->value case
}
return count($parent) ? $returnValue : rtrim($returnValue) . PHP_EOL;
}
答案 4 :(得分:-1)
使用php内部函数怎么样? http://php.net/manual/en/function.parse-ini-file.php