Kr4k4n
Kr4k4n

Reputation: 51

Multidimensional array into a ini file

I have some plain XML code that I need to first read from a service (got that sorted) and it looks like this:

<?xml version="1.0" encoding="UTF-8"?>
<bookcase>
<book>
   <id>1</id>
   <title>Murder1</title>
   <author>John doe</author>
   <heading>Reminder to read</heading>
   <body>A very exciting book etc</body>
</book>
<book>
   <id>2</id>
   <title>Murder2</title>
   <author>Jane doe</author>
   <heading>Reminder to read to</heading>
   <body>Also a very exciting book</body>
</book>
</bookcase>

Then I have this code to read it with JSON:

$xmlfile = file_get_contents($path);
$ob= simplexml_load_string($xmlfile);
$json  = json_encode($ob);
$configData = json_decode($json, true);

Output with var_dump($configData); gives:

array(1) { ["book"]=> array(2) { 
[0]=> array(5) { 
    ["id"]=> string(1) "1" 
    ["title"]=> string(7) "Murder1" 
    ["author"]=> string(8) "John doe" 
    ["heading"]=> string(16) "Reminder to read" 
    ["body"]=> string(24) "A very exciting book etc" } 
[1]=> array(5) { 
    ["id"]=> string(1) "2" 
    ["title"]=> string(7) "Murder2" 
    ["author"]=> string(8) "Jane doe" 
    ["heading"]=> string(19) "Reminder to read to" 
    ["body"]=> string(25) "Also a very exciting book" } 
               } 
} 

I found in another thread a function I thought that I could use but it seems not to be able to parse arrays that are multidimensional?

function write_ini_file($assoc_arr, $path, $has_sections=FALSE) { 
   $content = ""; 
   if ($has_sections) { 
    foreach ($assoc_arr as $key=>$elem) { 
        $content .= "[".$key."]\n"; 
        foreach ($elem as $key2=>$elem2) { 
            if(is_array($elem2)) 
            { 
                for($i=0;$i<count($elem2);$i++) 
                { 
                    $content .= $key2."[] = \"".$elem2[$i]."\"\n"; 
                } 
            } 
            else if($elem2=="") $content .= $key2." = \n"; 
            else $content .= $key2." = \"".$elem2."\"\n"; 
        } 
    } 
  } 
  else { 
    foreach ($assoc_arr as $key=>$elem) { 
        if(is_array($elem)) 
        { 
            for($i=0;$i<count($elem);$i++) 
            { 
                $content .= $key."[] = \"".$elem[$i]."\"\n"; 
            } 
        } 
        else if($elem=="") $content .= $key." = \n"; 
        else $content .= $key." = \"".$elem."\"\n"; 
    } 
  }


  if (!$handle = fopen($path, 'w')) { 
    return false; 
  }

  $success = fwrite($handle, $content);
  fclose($handle); 

  return $success;  }

  write_ini_file($configData, './data.ini', true);

Can anyone help figure out how to manage the function so I can save the array data in an ini file?

Update: Just want to share the code I found working for my purpose.

<?php
$path = ".\data.xml";

$xmlfile = file_get_contents($path);
    $ob= simplexml_load_string($xmlfile);
    $json  = json_encode($ob);
    $configData = json_decode($json, true);


foreach($configData as $section => $array) {
    foreach($array as $key => $values) {
        $ini[] = "\r\n"."[$section-$key]";
        foreach($values as $var => $val) {
            $ini[] = "$var = \"$val\"";
        }
    }
}

 $ini = implode("\r\n", $ini);
 nl2br($ini);
 file_put_contents('./data.ini', $ini);

 ?>

Gives a nice formatting like this into my INI-File:

[book-0]
id = "1"
title = "Murder1"
author = "John doe"
heading = "Reminder to read"
body = "A very exciting book etc"

[book-1]
id = "2"
title = "Murder2"
author = "Jane doe"
heading = "Reminder to read to"
body = "Also a very exciting book"

Al credits to AbraCadaver

Upvotes: 2

Views: 3012

Answers (1)

AbraCadaver
AbraCadaver

Reputation: 78984

So this works for an array structured like yours:

Option 1

foreach($configData as $section => $array) {
    $ini[] = "[$section]";
    foreach($array as $key => $values) {
        foreach($values as $var => $val) {
            $ini[] = "{$key}[$var] = \"$val\"";
        }
    }
}
$ini = implode("\n", $ini);

Yields the ini output:

[book]
0[id] = "1"
0[title] = "Murder1"
0[author] = "John doe"
0[heading] = "Reminder to read"
0[body] = "A very exciting book etc"
1[id] = "2"
1[title] = "Murder2"
1[author] = "Jane doe"
1[heading] = "Reminder to read to"
1[body] = "Also a very exciting book"

Parsing it using sections:

$array = parse_ini_string($ini, true);

Yields the same array you started with:

Array
(
    [book] => Array
        (
            [0] => Array
                (
                    [id] => 1
                    [title] => Murder1
                    [author] => John doe
                    [heading] => Reminder to read
                    [body] => A very exciting book etc
                )

            [1] => Array
                (
                    [id] => 2
                    [title] => Murder2
                    [author] => Jane doe
                    [heading] => Reminder to read to
                    [body] => Also a very exciting book
                )
        )
)

Option 2

Changing the innermost line to:

$ini[] = "{$var}[$key] = \"$val\"";

Yields a more traditional ini output:

[book]
id[0] = "1"
title[0] = "Murder1"
author[0] = "John doe"
heading[0] = "Reminder to read"
body[0] = "A very exciting book etc"
id[1] = "2"
title[1] = "Murder2"
author[1] = "Jane doe"
heading[1] = "Reminder to read to"
body[1] = "Also a very exciting book"

However reading it back into an array, the structure is different:

Array
(
    [book] => Array
        (
            [id] => Array
                (
                    [0] => 1
                    [1] => 2
                )

            [title] => Array
                (
                    [0] => Murder1
                    [1] => Murder2
                )

            [author] => Array
                (
                    [0] => John doe
                    [1] => Jane doe
                )

            [heading] => Array
                (
                    [0] => Reminder to read
                    [1] => Reminder to read to
                )

            [body] => Array
                (
                    [0] => A very exciting book etc
                    [1] => Also a very exciting book
                )
        )
)

Option 3

Based upon your comment:

foreach($configData as $section => $array) {
    foreach($array as $key => $values) {
        $ini[] = "[$section-$key]";
        foreach($values as $var => $val) {
            $ini[] = "$var = \"$val\"";
        }
    }
}
$ini = implode("\n", $ini);

Yields an ini with a section based on the index of the array appended by the key of the subarray, that will NOT parse into the original array:

[book-0]
id = "1"
title = "Murder1"
author = "John doe"
heading = "Reminder to read"
body = "A very exciting book etc"
[book-1]
id = "2"
title = "Murder2"
author = "Jane doe"
heading = "Reminder to read to"
body = "Also a very exciting book"

Option 4

An alternative if there will NOT be multiple hierarchies like book then:

foreach($configData as $section => $array) {
    foreach($array as $key => $values) {
        $ini[] = "[$key]";
        foreach($values as $var => $val) {
            $ini[] = "$var = \"$val\"";
        }
    }
}
echo $ini = implode("\n", $ini);

Will yield an ini with numbered sections that will parse into the original array:

[0]
id = "1"
title = "Murder1"
author = "John doe"
heading = "Reminder to read"
body = "A very exciting book etc"
[1]
id = "2"
title = "Murder2"
author = "Jane doe"
heading = "Reminder to read to"
body = "Also a very exciting book"

In any case, to write the file:

file_put_contents('./data.ini', $ini);

Upvotes: 4

Related Questions