Chris Tankersley

Multiple Config Files with Zend_Application

Posted on 2010-02-28

With the recent release of Manuscript, one of the things I added to the application was an installer. The installer is pretty basic and just asks for some database information that gets written to the config files.

This posed a problem. Zend_Config_Writer will only write to a file, not update it. I would need to read in all the sections of the application.ini file (production, testing, development) and take into account any sections added by users and dependencies, remove the old file and write the new one. That seemed very heavy handed and dangerous.

Zend_Config has a merge() function, so the idea came to me to use two config files. Keep the application.ini file for system values that are 'global' across installations, and then added a local.ini for things like DB settings. Zend_Config_Writer would just write local.ini settings to the global space and everything would be great. Merge the local settings into the application settings and your done!

A problem surfaced. Manuscript is built using Zend_Application. Zend_Application takes care of all the bootstrapping, reading the config files, and setting up all the dirty stuff for me. It also only takes the path of single config file. I have two config files. Crap.

Luckily Zend_Application doesn't automatically bootstrap itself, but it does load the configuration immediately. What I ended up doing was this:

$application = new Zend_Application(
    APPLICATION_ENV,
    APPLICATION_PATH . '/configs/application.ini'
);

$localConfigFile = APPLICATION_PATH.'/configs/local.ini';
if(is_file($localConfigFile)) {
    $config = new Zend_Config($application->getOptions(), true);
    $local  = new Zend_Config_Ini($localConfigFile);
    $config->merge($local);
    $application->setOptions($config->toArray());
}

$application->bootstrap()
            ->run();

You initialize Zend_Application like normal and call the default application.ini. Zend_Application makes that config file available as an array, so I pull the loaded config back out and pass it into a new array-based Zend_Config ($config in the above). I create a second config ($local) with Zend_Config_Ini.

Using merge(), I merge the $local file into the $config file. This gets me a proper representation of what I wanted. I push this config back into Zend_Application and then call the bootstrap. The bootstrap is none the wiser that it actually is using two config files and my database gets bootstrapped properly!

It is not as clean as I want it to be but it gets the job done and users can override or add their own config information to local.ini and not worry about editing the supplied config file in the release.


Comments