Manage application configuration in different modes

Info: This tutorial references the idea presented in Jonah's excellent blog article.

Application configuration determines how an Yii application should behave, because it is the only parameter passed in the entry script. An application, on the other hand, needs to behave differently under different circumstances. For example, an application may need different configurations when running in production mode, development mode and testing mode; In a team development environment, each developer may have his own database connection and thus require a customized application configuration. In this tutorial, we describe how to manage application configurations to fulfill all the above needs.

Before we start, we should note that an application configuration is stored as a PHP script. As a result, we can place any valid PHP code in it, which may make the configuration more 'intelligent' than simply returning an array of name-value pairs.

First, we create the main application configuration and store it in the file main.php. This file should contain all necessary configurations that are needed when the application is running in the production mode.

Second, we create the development application configuration and store it in the file dev.php. Because the development and main configurations are mostly the same, we create the former by inheriting it from the latter. We use [CMap::mergeArray] to implement the desired inheritance:

<?php
return CMap::mergeArray(
	require(dirname(__FILE__).'/main.php'), 
	array(
		'components'=>array(
			'db'=>array(
				// define DB connection used for development
			),
		),
	)
);

In the above, we first include main.php, and define the customized configuration array (the example shows defining a customized DB connection configuration). We then return the merged result of the two as the final development configuration. Note that we should not use PHP's array_merge() or array_merge_recursive() functions, as neither of them would merge the two arrays in the way we want.

We can similarly define the testing application configuration and store it in the file test.php.

In order to run the application in different modes (production, development, or testing), we should use the corresponding configuration in the entry script. To save the trouble of constantly modifying the entry script to switch the mode, we can create an entry script for each mode. For example, we can have index.php, index-dev.php and index-test.php, corresponding to production, development and testing mode, respectively. In production, we use index.php in the browser URL to access the application; in development, we use index-dev.php and in testing, we use index-test.php.

In a team development environment managed with some source control system (e.g. SVN, CVS, GIT), each developer may want to have his own application configuration (e.g. because he may have a different DB connection setting). In this case, we should only store main.php in the repository. The rest of the configuration files should only be kept in each developer's file system to avoid conflict of development configuration changes.

Tip: The same technique may also be applied to other PHP-based configurations. For example, if we store application parameters (accessed via Yii::app()->params) in a PHP file, we can use the above technique to customize parameters in different modes.

Links

Russian Version
Chinese Version