简体   繁体   English

PHP:具有N个元素的动态多维数组

[英]PHP: Dynamic multidimensional array with N number of elements

I'm trying to create an array that contains a config file, but I'm having trouble when some of the keys has the same name.我正在尝试创建一个包含配置文件的数组,但是当某些键具有相同的名称时我遇到了麻烦。 Let's say I have a config in this kind of format:假设我有一个这种格式的配置:

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

and that would be turned into an array like this with the idea, that there can be any amount of comma seperated key values:并且可以将其转换为这样的数组,即可以有任意数量的逗号分隔键值:

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"
  )
)

But I'm unable to get my head around it.但我无法理解它。 I've tried creating a foreach loop and inserting new array into the last array via references, but it takes only the first key set starting with same name.我尝试创建一个 foreach 循环并通过引用将新数组插入到最后一个数组中,但它只需要第一个以相同名称开头的键集。 Here's my current code and the result:这是我当前的代码和结果:

    $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);

result:结果:

Array
(
  [dinnes] => "salad"
  [dish] => Array
  (
    [fruit] => Array
    (
      [first] => Array
      (
        [name] => "apple"
      )
    )
  )
  [dressing] => Array
  (
    [name] => "french"
  )
)

There were various problems in it.里面有各种各样的问题。

The $config += $head; $config += $head; assignment would have overwritten entries.分配将覆盖条目。 Prefer array_merge for such cases.对于这种情况,首选array_merge And also $head was undefined;而且$head是未定义的; no idea where it came from.不知道它是从哪里来的。

Another simplification is just traversing the array structure using = &$last[$key] .另一个简化就是使用= &$last[$key]遍历数组结构。 This implicitly defines the subarray.这隐含地定义了子数组。 But you could of course retain the isset or use settype for explicity.但是您当然可以保留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);

Btw, the ereg functions are somewhat outdated.顺便说一句, ereg功能有些过时了。 And you could simplify this much more using a single preg_match_all or better yet reading in the ini-style file using parse_ini_file .您可以使用单个preg_match_all或更好地使用parse_ini_file读取 ini 样式文件来简化这一点。 - (See similar answer here php parse_ini_file oop & deep , albeit that uses an object structure.) - (在此处查看类似的答案php parse_ini_file oop & deep ,尽管它使用 object 结构。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM