将值写入INI文件

时间:2017-06-14 14:53:38

标签: php ini

我正在尝试存储多个数据,然后最后将数据推送到新的.ini文件中。我找到了可行的解决方案,但我希望先获取所有数据,然后在最后更新文件,但我发现的解决方案会立即更新文件!

我喜欢和工作的解决方案位于:https://stackoverflow.com/a/36997282/6613233

我试图让它收集信息,然后将其推送到文件末尾。我自己的尝试是在下面,但我一直在我的ini文件中获取数组。

代码:

$fbsettingsDB = parse_ini_file("location.ini", true);
$fbsettingsDB["id"]["value"] = $_POST['fbconfigid'];
$fbsettingsDB["location"]["value"] = $_POST['fbconfigcty'];
file_put_contents('location.ini', implode("\n", $fbsettingsDB));

以上是我想收集数据的方式。我有一堆进出语句的代码,我希望它继续进行。分配所需的值,最后继续将内容放在文件中,如上所示。

使用引用的代码我将不得不这样做:

config_set("location.ini", "id", "value", $_POST['fbconfigid']);
config_set("location.ini", "location", "value", $_POST['something']);
config_set("location.ini", "result", "value", $_POST['somethingelse']);

每次都会覆盖文件,在我看来只是疯了!对于我的想法有点过分,显然有一些方法可以满足我的需求,所以我可以在编辑/更改列表之后调用该函数一次,然后当我调用该函数时,它会抓取我所有已更改的数据并保存文件的方式我想要它!

1 个答案:

答案 0 :(得分:1)

我会尝试先解释为什么你的代码与其他代码相比不起作用。

你的inifile-array是由嵌套数组$array[section][item] = value构成的。第一个维度具有部分名称。第二个维度是部分中项目的名称。因此$fbsettingsDB["location"]包含一系列项目,其中"value"是一个。

Implode不检查数组是否嵌套。它只需要第一个维度(部分)并尝试将它们的值视为字符串。由于这些值实际上是项目数组,因此PHP只将其转换为文本“数组”。

除此之外,你不能只是破坏整个阵列。部分名称应该用方括号括起来,所以在这方面还有一些工作要做。

如果你检查the solution in the answer you referred to,你会发现它包含一个循环来处理第一层,即部分。 每个部分的项目数组分别用implode转换,然后用方括号中的部分名称作为前缀,并将整个批次附加到最终结果。

所以,你的意图是:你不想设置一个值并立即将其写回文件,但是更新多个值并只将最终结果写入磁盘。好吧,幸运的是,该功能不一定是原子的。它已经执行了三个单独的操作:从磁盘加载,修改数据以及将其序列化回磁盘。让我们看看它们是否可以在不同的函数中被隔离:

阅读数据。好吧,几乎不值得创建一个函数,但是如果你在相关函数的集合中使用相同的命名等等,它可能会使你的应用程序更加一致。

注意:我刚刚从头开始编写这些内容。没有PHP可以测试,因此它们可能包含轻微的语法错误。

所以这是:

// Loads ini file data
function config_read($config_file) {
    return parse_ini_file($config_file, true);
}

在加载的数据中设置配置。同样,几乎不值得拥有一个功能,但它增加了可读性并隐藏了如何构建ini文件数据,因此您在使用它时不必担心实现细节。请注意,数组是通过引用传递的。您指定的数组已更新。该函数不返回值。

// Update a setting in loaded inifile data
function config_set(&$config_data, $section, $key, $value) {
    $config_data[$section][$key] = $value;
}

然后写下来:

// Serializes inifile config data back to disk.
function config_write($config_data, $config_file) {
    $new_content = '';
    foreach ($config_data as $section => $section_content) {
        $section_content = array_map(function($value, $key) {
            return "$key=$value";
        }, array_values($section_content), array_keys($section_content));
        $section_content = implode("\n", $section_content);
        $new_content .= "[$section]\n$section_content\n";
    }
    file_put_contents($config_file, $new_content);
}

请注意,到目前为止,我没有修改任何代码。我把它包装在单独的函数中。如果您愿意,您甚至可以在另一个函数中调用这些函数,因此您仍然可以使用速记将所有内容写入磁盘。您将拥有原始功能,但没有重复的代码:

// Short-hand function for updating a single config value in a file.
function config_set_file($config_file, $section, $key, $value) {
    $config_data = config_read($config_file);
    config_set($config_data, $section, $key, $value)
    config_write($config_file, $section, $key, $value);
}

所以,现在你有了这个函数集合,你可以根据情况决定使用哪些函数。如果您只想更新单个值,也可以写下:

config_set_file("location.ini", "id", "value", $_POST['fbconfigid']);

但如果你有多个配置设置,你可以这样做:

// Load
$config_data = config_read("location.ini");
// Set multiple values
config_set($config_data, "id", "value", $_POST['fbconfigid']);
config_set($config_data, "location", "value", $_POST['something']);
config_set($config_data, "result", "value", $_POST['somethingelse']);
// Save
config_write($config_data, $config_file);

我可以想象你可以添加其他的shorthands,比如config_set_array_file,你可以像这样调用..我会把这个实现留给你练习。 ;)

array_config_set_file($config_file, array(
    "id" => $_POST['fbconfigid'],
    "location" => $_POST['something'],
    "result" => $_POST['somethingelse']));

在那之后,你可以将所有这些都变成IniFile类,以使它更好。 :)