6

I am writing a PHP application targeted at non-geeks, non-programmers. I need to create an option page with a bunch of "options" and then store those options...somewhere. Using a database application (MySQL/PostgreSQL/SQLite) is out of the question because it will require more configuration than the user needs to do (I don't want the user to do any kind of configuration if he doesn't want to). So the only solution left is to write the configuration to a configuration file. On the other hand, I also want that configuration file to be human-readable in case the user is a geek and he wants to edit the config file directly (or if he wants to edit the file remotely via SSH or any kind of reason...)

Here are the couple of potential solutions I found:

Using a JSON file...

...Retrieve the data from the file, using json_decode to convert the data, output it into HTML, retrieve any changes, encode back using json_encode, etc. You get the picture. There are a couple things that I don't like about this method, the main one being that the encoded JSON data using PHP will no be well formatted and very hard to edit without being reformatted beforehand.

Using an XML file

I won't describe that solution because I don't really like it either...and I don't know how to use XSLT and don't really want to learn...and because it's a pretty heavyweight solution, at least compared to the JSON solution. Correct me if I'm wrong.

Using an INI file

I love INI files, really I love them! I think they're really the most readable, and it's hard to mess up (ie: syntax errors). The problem with that solution is that there is no native way to write/edit an ini file. I found a topic showing a custom method to write one...that might be the solution I will adopt if I don't find anything better...

Using two files

That last solution seems as reasonable as the INI solution. In fact, I could use an INI file as "input" (the file that the user would edit if he wants to) and an XML/JSON file as output (the file that will be edited by PHP every time the user changes options using the web front-end). At this point, the best solution would be to ask the user to reload the configuration manually if he edited the config file directly, so that the "output" file is always up to date.


I know none of the solutions above are perfect, and that's why I created this topic to ask for advice. What is the best solution? Maybe (probably) I missed yet another solution.

One last thing: YAML isn't a valid solution because it's a lot easier to mess up the syntax if you're not used to it. PHP is not a solution either because editing PHP with PHP is a pain. PHP is only a good solution if I want to retrieve some configuration but not edit it directly via a web front-end.

Robert Audi
  • 8,019
  • 9
  • 45
  • 67
  • I think it will be much better if you can give us some idea of how your 'options' may look like. For example, are they mostly bunch of boolean values? arbitrary text values? one-line text values? multiple-value values (array)? – NawaMan Jun 21 '10 at 04:04
  • possible duplicate of [PHP, Reading File](http://stackoverflow.com/questions/2237291/php-reading-file) and related [I Need a Human Readable, Yet Parse-able Document Format](http://stackoverflow.com/questions/2595913/i-need-a-human-readable-yet-parse-able-document-format/2595970#2595970) – Gordon Jun 21 '10 at 06:56
  • I think compiling the config data from two sources is needlessly complicated. However, you *should* probably save a "last known good copy" of the config somewhere in case the user makes a change that breaks things. Also, be aware that the user may expect manual changes s/he makes to the config file to be preserved even if they later use the GUI. – cbednarski Jun 21 '10 at 07:11

5 Answers5

5

ini

I'd write ini files, myself. As you said, the syntax is very simple, and that's what you want in a config file. The ini format's "key+value" pairing is exactly what you'd get with a database—without the database.

Related SO you may have seen already: create ini file, write values in PHP

Plus you can use parse_ini_file() to read it.

XML

XML isn't all that bad. It may be more work to write it (and may not be as clear to the user as an ini file), but reading it is really easy.

Create it:


<?php
// Create file
$xml = new SimpleXMLElement( '<?xml version="1.0" ?><config></config>' );

// Add stuff to it
$xml->addChild( 'option1' );
$xml->option1->addAttribute( 'first_name', 'billy' );
$xml->option1->addAttribute( 'middle_name', 'bob' );
$xml->option1->addAttribute( 'last_name', 'thornton' );
$xml->addChild( 'option2' );
$xml->option2->addAttribute( 'fav_dessert', 'cookies' );

// Save
$xml->asXML( 'config.xml' );
?>

Read it:


<?php
// Load
$config = new SimpleXMLElement( file_get_contents( 'config.xml' ) );

// Grab parts of option1
foreach( $config->option1->attributes() as $var )
{
    echo $var.' ';
}

// Grab option2
echo 'likes '.$config->option2['fav_dessert'];
?>

Which gives you:

billy bob thornton likes cookies

Documentation for SimpleXML

Community
  • 1
  • 1
cbednarski
  • 11,718
  • 4
  • 26
  • 33
2

I'd go with the ini. They're really not that hard to write. I personally hate XML. It's so bloated... even if the file size doesn't matter, it still makes me cringe at it's wordiness and the amount of typing I have to do. Plus, people are dumb. They won't close their tags.

mpen
  • 272,448
  • 266
  • 850
  • 1,236
1

The standard way would be XML files. They don't create that much overhead and are easily extensible. However, JSON files are the easiest on the programming end.

I'd rank my preference:

  1. XML
  2. JSON
  3. ini (last resort)
Aaron Butacov
  • 32,415
  • 8
  • 47
  • 61
1

Unless you have 1000+ options, you really shouldn't worry about the XML file size. The goal here is to keep things easy for the user. This means that whichever method you choose (JSON shouldn't be one of them in my opinion), it should be heavily documented at each config line.

Your two file solution brings me back to the days of sendmail config and makes me shudder.

I would just go with XML, it's self documenting to a point <Email>hi@hi.hi</Email>

webbiedave
  • 48,414
  • 8
  • 88
  • 101
  • 1
    I don't think it needs to be heavily documented inline. Maintaining the docs inline will create unnecessary overhead. Newbies will use the GUI and advanced users should have some inkling of what the settings do, while details can be provided in the external docs / help file. A simple "see readme.txt > Config File" should suffice. – cbednarski Jun 21 '10 at 06:47
  • I would agree with that. Use a separate doc file instead. – webbiedave Jun 21 '10 at 11:19
1

Well, you could use PHP's serialize(), and although it is human readable, it isn't the most human readable thing there is. It's on the same level as JSON to implement.

chris12892
  • 1,634
  • 2
  • 18
  • 36