Double Quotation Marks in PHP ini Files

PHP conveniently offers the function parse_ini_file, which allows you to load settings stored in the same format as php.ini. File parsing is fast (on my machine loading a handful of settings takes about 1/10th the time of using DOM or SimpleXML to parse the equivalent information in an XML file), and the format is both human-readable and intuitive. Then it turns out that, at least as of 5.2, there’s no way to include a double quotation mark in option values, which pretty much renders the whole thing useless for all but very limited applications.

In a nutshell, the problem is that double quotation marks are used to enclose strings in option values in the file, sort of like this:

my.option="a string of information"

After parsing, the data returned in PHP looks like:

array(
  'my.option' => 'a string of information'
);

The issue is that parse_ini_file doesn’t provide an escape sequence within quotation marks. It just reads straight through the string until it finds a matching quotation mark and ends the string there. Typically, formats allow you place quotation marks within a quoted string either by using a backslash as an escape character (\") or by using two adjacent quotation marks (""). Neither of these are recognized by parse_ini_file, which leaves you pretty much out of luck.

You could add support for an escape character in your ini files. By passing the INI_SCANNER_RAW flag to parse_ini_file, you can get it to return unaltered option values, and you can then handle parsing them anyway you like. In my case that wasn’t a very attractive option. I was hoping to use the built-in ability to recognize boolean values, strings, and the like, rather than having to re-implement all of that myself.

As it turns out, there is another way you can include quotation marks in your ini files, and you can coax parse_ini_file into handling it for you. To see why it works, we first need to touch on a facet of how the built-in function handles strings. Much like other scanners, parse_ini_file will concatenate adjacent strings in a value, which allows you to quote only portions of a value if you choose. So, if we have a file like:

my.option = "this value " and " that value"

We’ll get back data that looks like:

array(
  'my.option' => 'this value and that value'
);

Notice that it strips out whitespace between the quoted strings and the unquoted word. This feature can be combined with the ability of parse_ini_file to expand constants you have defined in PHP within an ini file. Placing quotation marks within a string can then look a little like it does in the shell. In my case I decided to choose a fairly short constant name for the quotation mark since I didn’t want my strings getting too long and hard to read. I used _Q as the constant, so in the PHP code I have something like:

function load_ini_file() {
  if (!defined('_Q'))
    define('_Q', '"');
  parse_ini_file(, true)
}

In my ini file I can now have:

my.option = "I can now use _Q to embed quotation marks ("_Q") within a string"

And I’ll get back:

array(
  'my.option' => 'I can now use _Q to embed quotation marks (") within a string'
);

I have to admit, it makes me feel slightly dirty. I really wish I could have a more readable way to include quotation marks in my data, but in a pinch this little trick allowed me to do so, and I got to spend my time writing application code instead of routines for parsing option values that wouldn’t be of very high value to the overall project.

Comments

Very very useful tip.

Comments are now closed for this post.