我正在尝试创建一个包含配置文件的数组,但是当一些键具有相同名称时我遇到了麻烦。假设我有这种格式的配置:
dinner=salad
dish.fruit.first.name=apple
dish.fruit.first.juicy=true
dish.fruit.second.name=lettuce
dish.fruit.second.juicy=false
dressing.name=french
dressing.tasty=true
并且这会变成这样一个数组,并且可以有任意数量的逗号分隔键值:
Array
(
[dinner] => "salad"
[dish] => Array
(
[fruit] => Array
(
[first] => Array
(
[name] => "apple"
[juicy] => "true"
)
[second] => Array
(
[name] => "lettuce"
[juicy] => "false"
)
)
)
[dressing] => Array
(
[name] => "french"
[tasty] => "true"
)
)
但是我无法理解它。我已经尝试创建一个foreach循环并通过引用将新数组插入到最后一个数组中,但它只需要以相同名称开头的第一个键集。这是我当前的代码和结果:
$config = array();
$filehandle = @fopen($filename, "r");
while (!feof($filehandle))
{
$line = ereg_replace("/\n\r|\r\n|\n|\r/", "", fgets($filehandle, 4096));
$configArray = explode("=", $line);
$configKeys = explode(".", $configArray[0]);
$configValue = $configArray[1];
foreach ($configKeys as $key)
{
if (isset($head))
{
$last[$key] = array();
$last = &$last[$key];
}
else
{
$head[$key] = array();
$last = &$head[$key];
}
}
$last = $configValue;
$config += $head;
unset($head);
unset($last);
}
fclose($filehandle);
结果:
Array
(
[dinnes] => "salad"
[dish] => Array
(
[fruit] => Array
(
[first] => Array
(
[name] => "apple"
)
)
)
[dressing] => Array
(
[name] => "french"
)
)
答案 0 :(得分:2)
其中存在各种问题。
$config += $head;
作业会覆盖条目。对于此类情况,请更喜欢array_merge
。而$head
也未定义;不知道它来自哪里。
另一种简化只是使用= &$last[$key]
遍历数组结构。这隐含地定义了子数组。但您当然可以保留isset
或使用settype
表示明确。
$config = array();
$filehandle = @fopen(2, "r");
while (!feof($filehandle))
{
$line = ereg_replace("/\n\r|\r\n|\n|\r/", "", fgets($filehandle, 4096));
$configArray = explode("=", $line);
$configKeys = explode(".", $configArray[0]);
$configValue = $configArray[1];
$last = &$config;
foreach ($configKeys as $key)
{
$last = &$last[$key];
}
$last = $configValue;
}
fclose($filehandle);
顺便说一句,ereg
函数有点过时了。您可以使用单preg_match_all
或更好的方式使用parse_ini_file
在ini风格的文件中阅读,从而简化这一过程。 - (请参阅此处php parse_ini_file oop & deep的类似答案,尽管它使用的是对象结构。)