Extra flexibility in config environments

Hi guys,

Just started with the yii framework, looks like some great work is being done here.

Got a feature request, (I’m hoping it’s not already supported) and I don’t think it is, for extra flexibility in sepcifying the config environments.

The problem I have is that in our team, we need different test configurations for our different developers. (It’s also conceivable that we would need different ‘main’ configurations for different installations).

An easy example is this.

  • I am developing on a mac and have my own local copy of the database, which I’ve given one name, ‘paul-dev’ say (silly name I know, but for argument…).

  • Sam over there is working on windows, and his dev database is sitting on a linux server in the corner, and is called ‘linux-test’ say

This means that we need two different config/test.php files. The problem is, when I ‘svn commit’ my test.php to the repository, and Sam does an ‘svn update’ he’ll get a conflict with his settings.

There are similar issues if I have several webservers running the app, and we need different configurations for each of them. Maybe there are subnets etc. and NAT’ing going on which means databases are on different IP addresses, say.

What I’m proposing is, leaving main.php and test.php working fine for the developers who just need them, but having the ability to also do

test.paul-mac.php

test.sam-windows.php

main.server1.php

main.server2.php

these could inherit from test.php and main.php if they wanted to. Which one gets picked up could be controlled by an environment variable, YII_ENVIRONMENT, say.

If the environment variable is not set, then the index.php, index_test.php, bootstrap.php could just default to picking up main.php, test.php.

(In truth we could lose index.php and just go off an environment variable for test/dev, but maybe that’s another discussion).

Let me know what you guys think. If you reckon this is a good idea I’ll be happy to put it together and submit a patch.

Cheers,

Paul.

In our setups we often use a "local.php" and add it to svn:ignore. Then we add a "local-sample.php" to SVN which must be copied to local.php on checkout and should look like this:


<?php

return CMap::mergeArray(

    require(dirname(__FILE__).DIRECTORY_SEPARATOR.'main.php'),

    array(


        // put local config here. You can also override settings from main.php


        'components'=>array(

            'log'=>array(

                'routes'=>array(

                    array(

                        'class'=>'CWebLogRoute',

                    ),

                ),

            ),

            'db'=>array(

                'connectionString' => 'mysql:host=localhost;dbname=test',

                'username' => 'test',

                'password' => 'blablaba',

                // 'enableProfiling' => true,

                 //'enableParamLogging' => true,

            ),

);



In index.php we then replace main.php with local.php.

Thanks for that input Mike, that’s certainly a way around it, although it does entail a (small) change to the standard index.php to pick up a ‘local.php’ .

I do like my configurations to live under source control as well (especially the live ones).

It’s easy enough for me to change my index.php / bootstrap.php in each of my projects to get around this issue (thanks to the refreshingly clear way in which Yii is written! ), but do people think it’s something worth putting in the default?

(Running the risk of getting flamed, having an external variable storing the environment name is the way a Rails/Passenger setup works, and it works well).

You could of course also keep main.php and merge local.php there:


<?php

return CMap::mergeArray(

    array(

       // main config here

    ),

    require(dirname(__FILE__).DIRECTORY_SEPARATOR.'local.php')

);



The only problem left for me is, that i’d like to define YII_DEBUG in my local.php. But that doesn’t work. YII_DEBUG has to be defined before Yii is included in the index.php. So tried this in index.php:


$config=include(dirname(__FILE__).'/protected/config/main.php');

require_once('yii-1.0.10/yii.php');  // Yii is in my include_path

Yii::createWebApplication($config)->run();



but that doesn’t work with the above setup, because then CMap::arrayMerge() isn’t available in main.php.

OK, time to write some code to show what I mean





$environment = getenv('YII_ENVIRONMENT');

if (! $environment){

    $environment = 'main';

}

$config = dirname(__FILE__).'/protected/config/' . $environment . '.php';


if (! file_exists($config)){

    die("Couldn't find config file for environment: $environment");

}




In my shell I can export YII_ENVIRONMENT=paul-mac

In my apache VirtualHost I can SetEnv YII_ENVIRONMENT paul-mac

I can have all the different configurations under source control, and they won’t conflict, and they can happily inherit from main.php and just override what they need.

That YII_DEBUG thing is a pain though. You really want to set that in the configuration file, rather than having to mod your index.php. You want to control the differences between the environments your app is running in in a single config file really IMHO.

I changed the DEBUG line in index.php to load a constants.php file instead from config/ and moved the DEBUG constant to the new file. I’m also using the constants.php file to define application-specific constants such as version numbers. It’s also useful for defining custom paths for use in helpers and other components.

An alternate approach might be to load the constants file at the head of main.php, but I have not tried this. This would eliminate one line from index.php.