Author Topic: parse_ini_file() and Double Quotes  (Read 99 times)

Offline Fustrate

  • Aldo the Apache
  • Hero Member
  • Posts: 733
  • Gender: Male
  • Noxious Boxes
    • Fustrate
parse_ini_file() and Double Quotes
« on: July 29, 2010, 02:34:58 PM »
Ran into a problem with using .ini files and parse_ini_file(). If you want to include double quotes in a value... short story is, you can't.

Code: (data.ini) [Select]
; Testing comment
; Again.

[system]
blargh = "Do you hear the people sing"
singing = "the songs
of \"angry""
men"
it = is the music of a people

[margarine]
butter = mmm

Doesn't work. You end up with that line saying of \angry and you're left to wonder where they went. The simple solution is to do this:
Code: [Select]
$data = str_replace('\"', chr(7), file_get_contents('data.ini'));

print_r(str_replace(chr(7), '"', parse_ini_string($data)));
which takes the contents, replaces all escaped quotation marks with a BEL character (non-printing, majorly unused), and after parsing the string, replaces all BEL characters with quotation marks.

parse_ini_string() is only available in PHP >=5.3.0, which is higher than we'd like to go for requirements. There are one and a half other solutions that would be coupled with the one above - either write the BEL'd data to a temp file and parse it from there, or possibly (I have no idea about this) use a stream to fake the string being a file.

Thoughts? If worst comes to worst, we could write a simple .ini string compat function when parse_ini_string is undefined, or ditch plans for .ini altogether.

Offline Fustrate

  • Aldo the Apache
  • Hero Member
  • Posts: 733
  • Gender: Male
  • Noxious Boxes
    • Fustrate
Re: parse_ini_file() and Double Quotes
« Reply #1 on: July 29, 2010, 03:20:48 PM »
As an example of what *does* work...

Code: [Select]
// Yawn. Boring thing that we need below.
function str_replace_recursive($search, $replace, $subject)
{
foreach ($subject as $key => $data)
{
if (is_array($data))
$subject[$key] = str_replace_recursive($search, $replace, $data);
else
$subject[$key] = str_replace($search, $replace, $data);
}

return $subject;
}

function parse_ini_data($filename, $sections = false)
{
$data = str_replace('\"', chr(7), file_get_contents($filename));

if (function_exists('parse_ini_string'))
$data = parse_ini_string($data, $sections);
else
{
$tempname = tempnam('/tmp', 'ini');
$fp = fopen($tempname, 'w');
fwrite($fp, $data);
$data = parse_ini_file($tempname, $sections);
fclose($fp);
@unlink($tempname);
}

return str_replace_recursive(chr(7), '"', $data);
}

die(print_r(parse_ini_data('data.ini')));

It's just ugly, though.

Offline Lorel

  • Jr. Member
  • Posts: 57
Re: parse_ini_file() and Double Quotes
« Reply #2 on: July 29, 2010, 03:58:57 PM »
What's wrong with using " instead? Or even " as an encoding measure.


I'm not sure there's a need for multiple different varieties of input. JSON works perfectly well and if you're using UTF-8 in the first place, the inbuilt functions are just fine.

Offline Fustrate

  • Aldo the Apache
  • Hero Member
  • Posts: 733
  • Gender: Male
  • Noxious Boxes
    • Fustrate
Re: parse_ini_file() and Double Quotes
« Reply #3 on: July 29, 2010, 04:33:01 PM »
" is super lame. I don't want to have to type that out every time I want to use a quote...

JSON is another good alternative, but it's a bit more tedious to type. I know that a scricter format encourages following the standards, but newer coders will have a harder time unless you show them exactly how to do it (i.e. with an array and json_encode). You'll also run into formatting issues if you show them json_encode(array(...)), because they'll just toss in the single-line output and leave everyone else to try to wade through to find a few values they want to change.

I think having support for a few different formats is important in letting people choose whichever format is most comfortable to them. It would definitely be easier to lock people into the one format, but different formats are useful for different things.

Most internationalization benefits from INI:
Code: [Select]
hello_guest = "Hello, guest!"
current_time = "The current time is %1$s"
easter_egg = "Teehee! You found an Easter egg!"

but more complex items need JSON:
Code: [Select]
{
"months": {
"1":"January",
"2":"February",
"3":"March",
"4":"April",
"5":"May",
"6":"June",
"7":"July",
"8":"August",
"9":"September",
"10":"October",
"11":"November",
"12":"December"
}
}

I'd hate to force everything on JSON, because it's a lot of tedious formalities, and it has to be formatted again before it's readable (because nobody would seriously sit there and type JSON out).

Edit: It's actually easier to have months in INI format, too:
Code: [Select]
[months]
1 = January
2 = February
3 = March
4 = April
5 = May
6 = June
7 = July
8 = August
9 = September
10 = October
11 = November
12 = December
just make sure anything in a [section] is at the bottom of the file, et voila
« Last Edit: July 29, 2010, 05:21:59 PM by Fustrate »

Offline Dannii

  • Sr. Member
  • Posts: 388
  • Mind the volcano!
Re: parse_ini_file() and Double Quotes
« Reply #4 on: July 29, 2010, 08:05:06 PM »
Use YAML.

Offline Fustrate

  • Aldo the Apache
  • Hero Member
  • Posts: 733
  • Gender: Male
  • Noxious Boxes
    • Fustrate
Re: parse_ini_file() and Double Quotes
« Reply #5 on: July 29, 2010, 08:21:21 PM »
Not a lot of hosts have yaml compiled in PHP... we'd have to include a parser ourselves in order to do that. Also, its strict alignment is even more of a turn-off than JSON =\

Offline Dannii

  • Sr. Member
  • Posts: 388
  • Mind the volcano!
Re: parse_ini_file() and Double Quotes
« Reply #6 on: July 29, 2010, 09:29:59 PM »
Strict alignment? What do you mean?

Offline Fustrate

  • Aldo the Apache
  • Hero Member
  • Posts: 733
  • Gender: Male
  • Noxious Boxes
    • Fustrate
Re: parse_ini_file() and Double Quotes
« Reply #7 on: July 29, 2010, 09:50:12 PM »
Things like parent and child elements are created (and figured out by the parser) by their alignment levels.

Offline Dannii

  • Sr. Member
  • Posts: 388
  • Mind the volcano!
Re: parse_ini_file() and Double Quotes
« Reply #8 on: July 29, 2010, 10:33:02 PM »
AFAIK the only requirement is that all siblings are indented an equal number of spaces. If that's a turn off you must really dislike python :P

Offline Fustrate

  • Aldo the Apache
  • Hero Member
  • Posts: 733
  • Gender: Male
  • Noxious Boxes
    • Fustrate
Re: parse_ini_file() and Double Quotes
« Reply #9 on: July 29, 2010, 10:35:24 PM »
I absolutely *hate* python :P I believe in freedom of random indentation!