Reputation: 51
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
Reputation: 78984
So this works for an array structured like yours:
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
)
)
)
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
)
)
)
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"
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