Use application on production/development environment without making changes

  1. Server Configuration
  2. Changes to the application
  3. Configuration files

I like programing on my localhost, however it really bugged me to make changes to index.php & config files on my production server. After combining all available wiki articles on this topic and some trial and error this is what I use for my applications so I could just upload it to production server and it will work without any changes.

Server Configuration

To make this trick work you will have to add an environment variable to you server configuration. You could probably change it to use the IP or some other method, but I'm quite happy for now with environment variable. As I use virtual hosts for applications on my local machine, I just add an environment variable in my virtual host configuration: SetEnv APPLICATION_ENV "development". Give the variable the different name if you want (I use APPLICATION_ENV) and I use development as its value to load the appropriate config. If you don't use virtual hosts you could add this to your apache config or htaccess file (but this kind of beats the purpose of a tip because every time you re-upload htaccess file you will have to make changes to it).

Changes to the application

Modify your index.php file to look similarly to this:

// Set configurations based on environment
if( isset( $_SERVER['APPLICATION_ENV'] ) )
{
  // Set framework path
  $yii = dirname( __FILE__ ) . '/../../xampp/yii/yii-118/framework/yii.php';
  
  // Enable debug mode for development environment
  defined( 'YII_DEBUG' ) or define( 'YII_DEBUG', true );
  
  // Specify how many levels of call stack should be shown in each log message
  defined( 'YII_TRACE_LEVEL' ) or define( 'YII_TRACE_LEVEL', 3 );
  
  // Set environment variable
  $environment = 'development';
  // $environment = $_SERVER['APPLICATION_ENV']; // Uncomment for dynamic config files
}
else
{
  // Set framework path
  $yii = dirname( __FILE__ ) . '/../../yii/yii-118/framework/yii.php';

  // Set environment variable
  $environment = 'production';
}

// Include config files
$configMain = require_once( dirname( __FILE__ ) . '/protected/config/main.php' );
$configServer = require_once( dirname( __FILE__ ) . '/protected/config/server.'
  . $environment . '.php' );

// Include Yii framework
require_once( $yii );

// Run application
$config = CMap::mergeArray( $configMain, $configServer );
Yii::createWebApplication( $config )->run();

A short rundown of the code:

At first it checks if environment variable is set. If it's set it means we are working on development machine so it sets framework path, turns on the debug mode, and sets prefix for configuration file.

If environment variable is not set, it means application is on the production machine, so it sets a different framework path, and sets configuration files prefix as 'production';

When it gets the main configuration file which doesn't change for development and production machines and then it gets configuration file depending on the environment.

After that it just includes Yii framework, merges the config files and runs the application.

Configuration files

This is just the example to give you the idea how this trick works.

main.php is the shared config file between both environments. So part of it can be a database configuration:

// Database
'db' => array(
  'emulatePrepare' => true,
  // Set the charset of the connection
  'charset' => 'utf8',
  // Save null instead of empty strings
  'nullConversion' => PDO::NULL_EMPTY_STRING,
  // Cache queries
  'schemaCachingDuration' => 180,
),

server.development.php is the configuration file used on the development machine. So I can expand my database configuration with connection settings and enable profiling for it:

// Database
'db' => array(
  'connectionString' => 'mysql:host=localhost;dbname=yourdbname',
  'username' => 'devdbuser',
  'password' => 'devpass',
  // Enable profiling
  'enableProfiling' => true,
  'enableParamLogging' => true,
),

server.production.php is the configuration file used on the production machine. So I can expand my database configuration with connection settings:

// Database
'db' => array(
  'connectionString' => 'mysql:host=localhost;dbname=prod_datab',
  'username' => 'prod_dbuser',
  'password' => 'productiondbpass',
),

And that's all. You can work on your local machine, and then you decide to check how it looks on production server, you just upload the files and it works without any modifications.

You can change the code to better suit your needs, and if you have questions or suggestions just write me a message.

Extra

I haven't tried it yet, but looks like there's an extension which helps you out with different environments yii-environment extension