Parsing a configuration file

array parse_ini_file ( string filename [, bool process_sections])

When you have created a complex application in PHP, the chances are you will want to find a way to save your data so that you have a persistent store for application configuration options. The Windows .ini file format is a very simple way to store data in a structured manner. This is an example ini file:

; this is a comment

[Main]
LastRun = 1076968318
User = "Paul"

[Save]
SavePath = /home/paul
AutoSave = yes
SaveType = BINARY

Lines that start with a semicolon ; and also blank lines are ignored. Lines that contain a string surrounded by square brackets, such as [Main] above, are section titles. Sections are just there for organisational reasons as you see shortly - above you can see that the LastRun and User keys are under the Main section, and the SavePath, AutoSave, and SaveType are under the Save section.

Each key in the ini file has a value that follows the equals sign, and the value can either be a string (such as the value for User), a constant (such as the value for AutoSave and SaveType), or a number (such as the value for LastRun). You can actually use strings without quotes if you want to, as shown in the SavePath value - the quotes are just syntactic sugar that helps differentiate between a string and a constant. However, if your string contains nonalphanumeric characters such as = the quotes are mandatory to avoid confusion.

Because you can specify strings without quotes if they are fairly simple strings, the value for SaveType is actually interpreted as a string and sent back as such to PHP. However, one neat extra feature to parse_ini_file() is that it will compare the value of each key against the list of constants in the system and replace any constants it finds with the value of the constant. You can override this by putting quotes around the string - this is helpful if you don't want "yes" to be converted to 1 by PHP. While this might seem irrelevant, consider that the country code for Norway is "NO", which, if not surrounded by quotes, will be interpreted by PHP as the constant "no" and set to false.

By default, parse_ini_file() ignores section headers and returns each ini key and its value as an associative array. However, if you pass true as the second parameter it makes each section header an element in the return value and the values in that section as sub-elements in that array.

This next example shows parse_ini_file() in action parsing the previous ini file:

<?php
    define("BINARY", "Save was binary");
    $inifile = parse_ini_file("my.ini");
    var_dump($inifile);
    $inifile = parse_ini_file("my.ini", true);
    var_dump($inifile);
?>

As you can see, it parses the file twice: once ignoring section headers, and once not. Here is the output:

array(5) {
    ["LastRun"]=>
    string(10) "1076968318"
    ["User"]=>
    string(4) "Paul"
    ["SavePath"]=>
    string(10) "/home/paul"
    ["AutoSave"]=>
    string(1) "1"
    ["SaveType"]=>
    string(15) "Save was binary"
}

array(2) {
    ["Main"]=>
    array(2) {
        ["LastRun"]=>
        string(10) "1076968318"
        ["User"]=>
        string(4) "Paul"
    }

    ["Save"]=>
    array(3) {
        ["SavePath"]=>
        string(10) "/home/paul"
        ["AutoSave"]=>
        string(1) "1"
        ["SaveType"]=>
        string(15) "Save was binary"
    }
}

Notice how in both calls to var_dump(), BINARY gets recognised as a constant and replaced by its value, "Save was binary". Also notice that /home/paul was recognised as a string despite it not being enclosed in quotation marks.

As you can see, the first printout has all the ini values in one array, whereas the second has a top-level array containing the section headers, and each section header element was itself an array containing the section values.

Author's Note: There are several reserved words for ini file keys that you cannot use, such as "yes", "no", and "null".

Using ini files for configuration data is all well and good, but remember that storing sensitive data in there may cause security headaches. Many people name ini files with the .php extension so that their web server parses it as PHP. They then add a line to the top something like this:

; <?php exit;
?>

The reason for this is because the semicolon is an ini file comment, so parse_ini_file() will ignore it. However, it is not a comment in PHP, so PHP will call the exit() function and terminate the script. As a result, it is not possible to call the script directly through a browser; only through parse_ini_file().

While this idea has merit, it is simply asking for trouble. What if a new version of Apache or PHP is installed and, temporarily, stops the .php extension from working? Yes, it is not a likely scenario, but why bother taking the risk? Your best bet is just to place the ini file outside of your public HTML folder so that only local users can access it.

 

Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Summary >>

Previous chapter: File checksums

Jump to:

 

Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.