Ok, here’s what I’ve come up with:
- In all console.php, main.php and test.php the database thing I’m defining as follows:
'components'=>array(
'db' => require(dirname(__FILE__).'/'.Y_DB.'_db.php'),
- under protected.config I’ve created files dev_db.php, test_db.php, etc. as such:
<?php
return array(
'class' => 'system.db.CDbConnection',
'connectionString' => 'mysql:host=localhost;dbname=appdatabase_dev',
...
);
and appdatabase_dev becomes app database_test for test.php, appdatabase_live to be used in production environment.
- now there’s a need to automatically select proper Y_DB. There’s three things to consider:
-
based on the operational environment (dev server, qa server, …)
-
there should be a way to override the database for the current environment.
-
the application can be run as a web app, as a cron script, as a phpunit test
Phew, too many ‘whishes’, not?
Here’s my index.php:
<?php
// where we at?
define('ENVIRONMENT',
getenv('Y_ENV')
&& in_array(getenv('Y_ENV'), array('dev', 'qa', 'stage', 'live'))
? getenv('Y_ENV')
: 'dev');
define('Y_DB', getenv('Y_DB') ? getenv('Y_DB') : ENVIRONMENT);
// load an environment-specific config file
//$config = dirname(__FILE__) . "/../protected/config/" . ENVIRONMENT . '.php';
// load main config file
$config = dirname(__FILE__) . "/../protected/config/main.php";
// set important paths
$yii=dirname(__FILE__).'/../framework/yii.php';
// environment-specific stuff (fine-tuning things)
switch (ENVIRONMENT)
{
case 'live':
case 'qa':
break;
case 'dev':
defined('YII_DEBUG') or define('YII_DEBUG',true);
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL',3);
break;
}
require_once($yii);
// run the app or print the $config variable, up to you.
Yii::createWebApplication($config)->run();
//print "config: $config\n";
Other entry points are similar to index.php. index-test.php, for instance, loading test.php instead of index.php. A commented line
//$config = dirname(__FILE__) . "/../protected/config/" . ENVIRONMENT . '.php';
technically allows to load an environment-specific config file, but at the moment it is overkill for me.
Ok, now the question is how to do the automatic switching (i.e. where these env. vars are coming from)?
Here it is.
On every server set the Y_ENV var at these locations:
APACHE: /etc/apache2/envvars
CRON /etc/crontab
BASH: /etc/environment
for instance,
Y_ENV=dev
It might be one of dev, prod, qa.
This is it. You run your app from web, from console, from phpunit and it uses whatever environment is appropriate.
Now, how to overwrite the database in case you want to temporarily switch to another database?
Easy:
shell# Y_DB=db_qa phpunit unit/testWhatever.php
The same way it is possible to run migrate scripts on every server without changing config files.