Convert Array to an .Ini File

Multidimensional array into a ini file

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

Convert a parse ini to array / objects

Your table is being generated so PHP & Ini file are fine but HTML code you are generating is incorrect so either DataTable plugin or jQuery DOM parser is confused.

Please fix it and it should work fine.

Sample Image

  • Put jquery+datatables js/css into <head> section.
  • You use multiple <tbody> and you put </tr> after </tbody>

So basically you shoud put echo "</tbody>"; outside loop so

echo "<tbody>"; // <<< HERE
foreach ($ini_array as $key => $value) {

echo "<tr>";
for ($i = 0; $i < 12; $i++) {
echo "<td>";
echo ($value[$getstats[$i]]);
echo "</td>";
}
echo "</tr>";
}
echo "</tbody>"; // <<< HERE


I'm wondering is it because the data type? http://www.datatables.net/manual/data tells you that the accepted data types are arrays, objects, and instances.

No, your code its fine as manual says Data can be read from DOM. You need arrays/objects/instances if you create table straight from javascript.

See below:

DOM

When DataTables starts up, it will automatically check the table it is operating on for data that already exists inside it and use it for the table (note that it will throw this data away if you pass in data using data or ajax to get new data!). This is the simplest method of using DataTables - working with a regular HTML table.

Note that when using a DOM sourced table, DataTables will use arrays as the data source (see above) by default, although you could use the columns.data option to have it construct objects for the row data instead.

http://www.datatables.net/manual/data#DOM

Use ConfigParser to read an array from ini file

This syntax, where subscriber[] automatically makes subscriber into a list of multiple values, is not a feature of .ini files in general, nor of ConfigParser; it's a feature of Zend_Config_Ini.

In Python, a ConfigParser ini file creates a dict mapping each key to its value. If you have more than one value, it will just override previous values. The magic [] suffix means nothing.

However, the ConfigParser constructor lets you specify a custom dictionary type or factory, in place of the default OrderedDict.

One simple solution would be to use a defaultdict(list) (or an OrderedDefaultDict, which there are recipes for in the docs) for the underlying storage, have __setitem__(self, key, value) do self.dd[key].append(value), and delegate everything else normally. (Or, if you prefer, inherit from defaultdict, override the constructor to pass list to the super, and then just don't override anything but __setitem__.) That will make all of your values into lists.

You could even do something hacky where a value that's only seen once is a single value, but if you see the same name again it becomes a list. I think that would be a terrible idea (do you really want to check the type of config.get('smtp', 'subscriber[]') to decide whether or not you want to iterate over it?), but if you want to, How to ConfigParse a file keeping multiple values for identical keys? shows how.

However, it's not at all hard to reproduce the exact magic you're looking for, where all keys ending in [] are lists (whether they appear once or multiple times), and everything else works like normal (keeps only the last value if it appears multiple times). Something like this:

class MultiDict(collections.OrderedDict):
def __setitem__(self, key, value):
if key.endswith('[]'):
super(MultiDict, self).setdefault(key, []).append(value)
else:
super(MultiDict, self).__setitem__(key, value)

This obviously won't provide all of the extended features that Zend_Config_Ini adds on top of normal .ini files. For example, [group : subgroup : subsub] won't have any special meaning as a group name, nor will key.subkey.subsub as a key name. PHP values TRUE, FALSE, yes, no, and NULL won't get converted to Python values True, False, True, False, and None. Numbers won't magically become numbers. (Actually, this isn't a feature of Zend_Config_Ini, but a misfeature of PHP's leaky typing.) You have to use # comments, rather than freely mixing #, ;, and //. And so on. Any of those features that you want to add, you'll have to add manually, just as you did this one.

As I suggested in a comment, if you really want to have more than two levels of hierarchy, you may be better off with a naturally infinitely-hierarchical format, where any value can be a list or dict of other values.

JSON is ubiquitous nowadays. It may not be quite as human-editable as INI, but I think more people are familiar with it than INI in 2014. And it has the huge advantage that it's a standardized format, and that both Python (2.6+) and PHP (5.2+) come with parsers and pretty-printers for in their standard libraries.

YAML is a more flexible and human-editable format. But you will need third-party modules in both languages (see the list at the YAML site). And it can also bring in some security concerns if you're not careful. (See safe_load and friends in the PyYAML docs; most other libraries have similar features.)

php ini creating arrays with parse_ini_file

It returns an associative array. Then, to parse the east states into an array, you could do:
$eastStates = explode(', ', $ini['States']['east']); if your data is indeed in the format you described. Note that you can create true arrays in ini format, see the documentation.

How to put a 2 array variables in config (.ini) file?

Put array elements in a comma separated list, then write some VBscript to parse these values.

strReportPath = /davaoccc,/calambaccc,/cebuccc

strFilePut= 0970*.txt,0979*.txt,0983*.txt

I assume all values are read as text, so you can drop the string quotes.

How can i parse an ini file as object

You can use json_encode() and json_decode() to achive this:

$file = 'config.ini';
if (!file_exists($file)) {
$file = 'config.sample.ini';
}
$config = parse_ini_file($file, true);
// convert to data to a json string
$config = json_encode($config);
// convert back from json, the second parameter is by
// default false, which will return an object rather than an
// associative array
$config = json_decode($config);

PHP Config.ini file parsing with multi-level arrays

OK, so you can look at using sections and the array syntax for INI files such as:

[site]
social[twitter] = URL
social[facebook] = URL
social[google-plus] = URL

Then pass true as the second argument:

$config = parse_ini_file(__DIR__ ."/../config.ini", true);

Or to build using your existing INI structure (adapted from How to access and manipulate multi-dimensional array by key names / path?):

$array = array();

foreach($config as $path => $value) {
$temp = &$array;
foreach(explode('.', $path) as $key) {
$temp =& $temp[$key];
}
$temp = $value;
}
$config = $array;
print_r($config);


Related Topics



Leave a reply



Submit