views:

172

answers:

4

I have a fairly large MVC PHP web app (custom, no framework) that uses a several-hundred-line XML file for configuration. The config data has a fairly complex structure, which is very elegantly represented in XML but not so easily read or written using the DOM. All reading and writing of config data goes through a Config class, which has accessor methods for each type of config data. Since each XML node is different, most of the methods use their own custom code. This class is currently around 2000 lines long and I don't like it. A database is not available.

It has occurred to me that perhaps a better way to persist config data would be to create some config classes and use object serialization to a file.

What are some best practices for handling complex config data?

A: 

I'm not really a fan of it, but one of the upsides of XML configuration is that it's at least theoretically hand-editable. With a serialized PHP object of any complexity, calling it hand-editable would be a real stretch; it's only slightly less difficult and error-prone than modifying strings in a binary executable using a hex editor.

So if you want to be friendly to config file editing outside your interface, PHP object serialization is not the way to go. If you don't care about that, though, it'll probably work out pretty well.

For what it's worth, I'd strongly suspect that the custom code for your XML nodes could largely be factored out and generalized.

chaos
+2  A: 

Have you considered SQLite?

It is a lightweight standalone database that is essentially a file. The database can be used locally or remotely. If you are able to persist your configuration to a file it should also be possible to persist to a SQLite database.

You may want to consider JSON as another option for serialization. It is theoretically still human readable and has the benefit of being more "Object" like in its final representation which might make the access code a little simpler. And the other benefit is that you could persist all or part of the model to the client side for processing. But then you have to introduce some javascript into your app which may or may not be what you want.

Gordon Potter
A: 

If you like the layout of the configuration structure, I think you'd be better off refactoring the existing code base for the configuration handler. I don't know if you're going to get much of a gain from serialization. If anything, i think it would be slightly difficult to debug in case the structure changes.

Sergey
A: 

INI files is the way I use to store configuration in Zend Framework, look at the sample config:

http://www.framework.zend.com/manual/en/zend.config.adapters.ini.html

; Production site configuration data
[production]
webhost                  = www.example.com
database.adapter         = pdo_mysql
database.params.host     = db.example.com
database.params.username = dbuser
database.params.password = secret
database.params.dbname   = dbname

; Staging site configuration data inherits from production and
; overrides values as necessary
[staging : production]
database.params.host     = dev.example.com
database.params.username = devuser
database.params.password = devsecret

Reading configuration:

$config = new Zend_Config_Ini('/path/to/config.ini', 'staging');

echo $config->database->params->host;   // prints "dev.example.com"
echo $config->database->params->dbname; // prints "dbname"

Writing configuration:

// Load all sections from an existing config file, while skipping the extends.
$config = new Zend_Config_Ini('config.ini',
                              null,
                              array('skipExtends'        => true,
                                    'allowModifications' => true));

// Modify a value
$config->production->hostname = 'foobar';

// Write the config file
$writer = new Zend_Config_Writer_Ini(array('config'   => $config,
                                           'filename' => 'config.ini'));
$writer->write();

Each node of configuration can be converted to array, as well as complex array can be used to create configuration class instance and to save it to file.

This type of configuration is really human-readable and editable.

Maybe you should try to create some similar solution.

Sergey 'm17' Kolosov