0

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. 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"
  )
)
1
  • 3
    Have you considered instead a different format for the configuration file? A JSON object would be trivial to deal with. Commented Jun 2, 2011 at 21:53

1 Answer 1

2

There were various problems in it.

The $config += $head; assignment would have overwritten entries. Prefer array_merge for such cases. And also $head was undefined; no idea where it came from.

Another simplification is just traversing the array structure using = &$last[$key]. This implicitly defines the subarray. But you could of course retain the isset or use settype for explicity.

$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. 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. - (See similar answer here php parse_ini_file oop & deep, albeit that uses an object structure.)

Sign up to request clarification or add additional context in comments.

1 Comment

hot diggity, thanks! yes, that makes sense now that I see it. I knew there were easier solution to this :P

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.