Yii 1.1: Use different environments (development, production, etc) in your app with EASY Environment Class

7 followers

Info: An extension was created based on this wiki page. See: http://www.yiiframework.com/extension/yii-environment/

Hi, I was having problems each time I had to test the site or edit something on my local machine, like changing the db connection, change the debug mode to false, the trace level to 0, disable Gii, etc. So I created a class to resolve all my problems, hope to help you in your projects!

Instructions

Configuring the Easy Environment class

  1. Create a new file in the config folder, name it 'environment.php'.

  2. Paste the following code in your 'environment.php' file.

/**
     * This class helps you to config your Yii application
     * environment.
     * Any comments please post a message in the forum
     * Enjoy it!
     *
     * @name Environment
     * @author Fernando Torres | Marciano Studio
     * @version 1.0
     */
 
    class Environment {
 
        const DEVELOPMENT = 100;
        const TEST        = 200;
        const STAGE       = 300;
        const PRODUCTION  = 400;
 
        private $_mode = 0;
        private $_debug;
        private $_trace_level;
        private $_config;
 
 
        /**
         * Returns the debug mode
         * @return Bool
         */
        public function getDebug() {
            return $this->_debug;
        }
 
        /**
         * Returns the trace level for YII_TRACE_LEVEL
         * @return int
         */
        public function getTraceLevel() {
            return $this->_trace_level;
        }
 
        /**
         * Returns the configuration array depending on the mode
         * you choose
         * @return array
         */
        public function getConfig() {
            return $this->_config;
        }
 
 
        /**
         * Initilizes the Environment class with the given mode
         * @param constant $mode
         */
        function __construct($mode) {
            $this->_mode = $mode;
            $this->setConfig();
        }
 
        /**
         * Sets the configuration for the choosen environment
         * @param constant $mode
         */
        private function setConfig() {
            switch($this->_mode) {
                case self::DEVELOPMENT:
                    $this->_config      = array_merge_recursive ($this->_main(), $this->_development());
                    $this->_debug       = TRUE;
                    $this->_trace_level = 3;
                    break;
                case self::TEST:
                    $this->_config      = array_merge_recursive ($this->_main(), $this->_test());
                    $this->_debug       = FALSE;
                    $this->_trace_level = 0;
                    break;
                case self::STAGE:
                    $this->_config      = array_merge_recursive ($this->_main(), $this->_stage());
                    $this->_debug       = TRUE;
                    $this->_trace_level = 0;
                    break;
                case self::PRODUCTION:
                    $this->_config      = array_merge_recursive ($this->_main(), $this->_production());
                    $this->_debug       = FALSE;
                    $this->_trace_level = 0;
                    break;
                default:
                    $this->_config      = $this->_main();
                    $this->_debug       = TRUE;
                    $this->_trace_level = 0;
                    break;
            }
        }
 
 
        /**
         * Main configuration
         * This is the general configuration that uses all environments
         */
        private function _main() {
            return array(
 
                    // Base Path
                    'basePath' => dirname(__FILE__).DIRECTORY_SEPARATOR.'..',
 
                    // Project Name
                    'name' => 'Project name',
 
                    // Preloading 'log' component
                    'preload'=>array('log'),
 
                    // autoloading model and component classes
                    'import' => array(
                            'application.models.*',
                            'application.components.*',
                    ),
 
                    // Application components
                    'components' => array(
                            'user' => array(
                            // enable cookie-based authentication
                                    'allowAutoLogin'=>true
                            ),
 
                            // Error Handler
                            'errorHandler'=>array(
                                        'errorAction'=>'site/error',
                             ),
 
                            // URLs in path-format
                            'urlManager'=>array(
                                    'urlFormat'=>'path',
                                    'rules'=>array(
                                            '<controller:\w+>/<id:\d+>'=>'<controller>/view',
                                            '<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
                                            '<controller:\w+>/<action:\w+>'=>'<controller>/<action>'
                                    ),
                            ),
                    ),
 
                    // Application-level parameters
                    'params'=>array(
                            'adminEmail'=>'admin@example.com',
                            'environment'=> $this->_mode
                    )
            );
        }
 
 
        /**
         * Development configuration
         * Usage:
         * - Local website
         * - Local DB
         * - Show all details on each error.
         * - Gii module enabled
         */
        private function _development () {
 
            return array(
 
                    // Modules
                    'modules'=>array(
                            'gii'=>array(
                                    'class'=>'system.gii.GiiModule',
                                    'password'=>'your password',
                                    'ipFilters'=>array(),
                                    'newFileMode'=>0666,
                                    'newDirMode'=>0777,
                            ),
                    ),
 
                    // Application components
                    'components' => array(
 
                            // Database
                            'db'=>array(
                                    'connectionString' => 'Your connection string to your local development server',
                                    'emulatePrepare' => false,
                                    'username' => 'admin',
                                    'password' => 'password',
                                    'charset' => 'utf8',
                            ),
 
                            // Application Log
                            'log'=>array(
                                    'class'=>'CLogRouter',
                                    'routes'=>array(
                                    // Save log messages on file
                                            array(
                                                    'class'=>'CFileLogRoute',
                                                    'levels'=>'error, warning,trace, info',
                                            ),
                                            // Show log messages on web pages
                                            array(
                                                    'class'=>'CWebLogRoute',
                                                    'levels'=>'error, warning, trace, info',
                                            ),
 
                                    ),
                            ),
                    ),
            );
        }
 
 
        /**
         * Test configuration
         * Usage:
         * - Local website
         * - Local DB
         * - Standard production error pages (404,500, etc.)
         * @var array
         */
        private function _test() {
            return array(
 
                    // Application components
                    'components' => array(
 
                            // Database
                            'db'=>array(
                                    'connectionString' => 'Your connection string to your local testing server',
                                    'emulatePrepare' => false,
                                    'username' => 'admin',
                                    'password' => 'password',
                                    'charset' => 'utf8',
                            ),
 
 
                            // Fixture Manager for testing
                            'fixture'=>array(
                                    'class'=>'system.test.CDbFixtureManager',
                            ),
 
                            // Application Log
                            'log'=>array(
                                    'class'=>'CLogRouter',
                                    'routes'=>array(
                                            array(
                                                    'class'=>'CFileLogRoute',
                                                    'levels'=>'error, warning,trace, info',
                                            ),
 
                                            // Show log messages on web pages
                                            array(
                                                    'class'=>'CWebLogRoute',
                                                    'levels'=>'error, warning',
                                            ),
                                    ),
                            ),
                    ),
            );
        }
 
        /**
         * Stage configuration
         * Usage:
         * - Online website
         * - Production DB
         * - All details on error
         */
        private function _stage() {
            return array(
 
                    // Application components
                    'components' => array(
                    // Database
                            'db'=>array(
                                    'connectionString' => 'Your connection string to your production server',
                                    'emulatePrepare' => false,
                                    'username' => 'admin',
                                    'password' => 'password',
                                    'charset' => 'utf8',
                            ),
 
                            // Application Log
                            'log'=>array(
                                    'class'=>'CLogRouter',
                                    'routes'=>array(
                                            array(
                                                    'class'=>'CFileLogRoute',
                                                    'levels'=>'error, warning, trace, info',
                                            ),
 
                                    ),
                            ),
                    ),
            );
        }
 
        /**
         * Production configuration
         * Usage:
         * - online website
         * - Production DB
         * - Standard production error pages (404,500, etc.)
         */
        private function _production() {
            return array(
 
                    // Application components
                    'components' => array(
 
                            // Database
                            'db'=>array(
                                    'connectionString' => 'Your connection string to your production server',
                                    'emulatePrepare' => false,
                                    'username' => 'admin',
                                    'password' => 'password',
                                    'charset' => 'utf8',
                            ),
 
 
                            // Application Log
                            'log'=>array(
                                    'class'=>'CLogRouter',
                                    'routes'=>array(
                                            array(
                                                    'class'=>'CFileLogRoute',
                                                    'levels'=>'error, warning',
                                            ),
 
                                            // Send errors via email to the system admin
                                            array(
                                                    'class'=>'CEmailLogRoute',
                                                    'levels'=>'error, warning',
                                                    'emails'=>'admin@example.com',
                                            ),
                                    ),
                            ),
                    ),
            );
        }
    }// END Environment Class
  1. Change the configuration for each environment:
    • DEVELOPMENT
    • TEST
    • STAGE
    • PRODUCTION

Configuring your index.php file

  1. Open your index.php file an replace all the code with the following code:*
// Change the following paths if necessary
    require_once(dirname(__FILE__).'/protected/config/environment.php');
    $environment = new Environment(Environment::DEVELOPMENT) ;
 
    $yii = dirname(__FILE__).'/../../framework/yii.php';
 
    defined('YII_DEBUG') or define('YII_DEBUG',$environment->getDebug());
    defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', $environment->getTraceLevel());
 
    require_once($yii);
    Yii::createWebApplication($environment->getConfig())->run();

Changing your environment

  1. To change the environment just you have to change the following code:
//For development
    $environment = new Environment(Environment::DEVELOPMENT); 
 
    //For test
    $environment = new Environment(Environment::TEST); 
 
    //For stage
    $environment = new Environment(Environment::STAGE); 
 
    //For production
    $environment = new Environment(Environment::PRODUCTION);

Get your actual environment

  1. You can check inside your application in what environment you are working with the following code:
// This will return the environment code number
    $currentEnvironment = Yii::app()->getParams()->environment;
 
    // Compare if the current environment is lower than production
    if($currentEnvironment < Environment::PRODUCTION){
       //Your code here...
    }else{
       //Your code here...
    }

Enjoy it! ;D

Total 5 comments

#32 report it
marcovtwout at 2010/10/07 10:11am
Solution with complete config seperation (addition)

To use my solution with testing, modify your protected/tests/bootstrap.php like this:

<?php
 
$yiit=dirname(__FILE__).'/../../../yii/framework/yiit.php';
 
// set environment
require_once(dirname(__FILE__) . '/../../protected/config/Environment.php');
$env = new Environment('TEST'); //override
 
// run Yii app
require_once($yiit);
require_once(dirname(__FILE__).'/WebTestCase.php');
Yii::createWebApplication($env->getConfig())->run();
#33 report it
marcovtwout at 2010/10/07 10:06am
Solution with complete config seperation (note)

Merging config arrays is not working as I expected when both arrays have a certain value. Yii is using CMAP::mergeArray to do this properly. To fix this, you can use:

// Merge config arrays into one
//$this->_config = array_merge_recursive($config, $configSpecific);
 
        require_once(dirname($yiiPath). DIRECTORY_SEPARATOR . 'base' . DIRECTORY_SEPARATOR . 'CComponent.php');
        require_once(dirname($yiiPath). DIRECTORY_SEPARATOR . 'collections' . DIRECTORY_SEPARATOR . 'CMap.php');
        $this->_config = CMap::mergeArray($config, $configSpecific);

I will see about working out a solution where the config files don't have to be merged up front, to keep from including Yii files before the webapp is created.

#34 report it
marcovtwout at 2010/10/07 09:25am
Solution with complete config seperation

Based on the versions from authors above, I created my own version of this script.

There is no environment specific code in the Environment.php class, everything is seperated into the config files. Impact on changing the index.php is minimal, but the configuration files need some slight modifications to incorporate the extra attributes. I might also turn them into classes at some point.

Environment is determined by Apache's SetEnv, but this can be easily changed at Environment::getMode()

Here is the code.

protected/config/Environment.php

<?php
 
/**
 * Simple class used to set configuration and debugging depending on environment.
 * This allows for a custom Yii path, debugging vars, and config array.
 *
 * Environment is determined by $_SERVER[YII_ENVIRONMENT], created
 * by Apache's SetEnv directive
 * This can be done in the httpd.conf or in a .htaccess file for ease of use.
 * See: http://httpd.apache.org/docs/1.3/mod/mod_env.html#setenv
 * 
 *******************************************************************************
 *
 * Index.php usage example:
 * 
 * // set environment
 * require_once(dirname(__FILE__) . '/protected/config/Environment.php');
 * $env = new Environment();
 * //$env = new Environment('PRODUCTION'); //override
 * 
 * // set debug and trace level
 * defined('YII_DEBUG') or define('YII_DEBUG', $env->getDebug());
 * defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', $env->getTraceLevel());
 * 
 * // run Yii app
 * require_once($env->getYiiPath());
 * Yii::createWebApplication($env->getConfig())->run();
 *
 *******************************************************************************
 *
 * Modify your config/main.php like this:
 *
 * // Set yiiPath (add extra ../../)
 * $yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 *
 * // Set YII_DEBUG and YII_TRACE_LEVEL flags
 * $debug = true;
 * $traceLevel = 0;
 *
 * // Set config array
 * $config = array(
 *
 *******************************************************************************
 *
 * Create config/mode_<mode>.php files for the different modes
 * These will override or merge attributes
 *
 * // Set yiiPath (add extra ../../)
 * //$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 *
 * // Set YII_DEBUG and YII_TRACE_LEVEL flags
 * $debug = false;
 * $traceLevel = 0;
 *
 * // Set specific config
 * $configSpecific = array(
 *
 *******************************************************************************
 *
 * Usage example for checking environment in code:
 *
 * // Compare if the current environment is lower than production
 * $currentEnvironment = Yii::app()->getParams()->environment; //gets integer
 * if ($currentEnvironment < Environment::PRODUCTION) {
 *     //do this
 * } else {
 *     //do that
 * }
 *
 *******************************************************************************
 *
 * Original sources: http://www.yiiframework.com/doc/cookbook/73/
 *
 * @name Environment
 * @author Marco van 't Wout | Tremani
 * @version 1.0
 * @property string mode the current environment mode
 * @property boolean debug the debug flag
 * @property integer traceLevel the trace level
 * @property string yiiPath path to the Yii framework
 * @property string config the merged config array
 * 
 */
class Environment
{
 
    // $_SERVER[SERVER_VAR]
    const SERVER_VAR = 'YII_ENVIRONMENT';
    const MAIN_CONFIG = 'main.php';
 
    // Modes
    const DEVELOPMENT = 100;
    const TEST = 200;
    const STAGE = 300;
    const PRODUCTION = 400;
 
    // Current mode
    private $_mode;
 
    // Environment properties
    private $_debug;
    private $_traceLevel;
    private $_yiiPath;
    private $_config;
 
    /**
     * Initilizes the Environment class with the given mode
     * @param constant $mode
     */
    function __construct($mode = null)
    {
        $this->_mode = $this->getMode($mode);
        $this->setEnvironment();
    }
 
    /**
     * Get current environment mode depending on environment variable
     * @param <type> $mode
     * @return <type>
     */
    private function getMode($mode = null)
    {
        // If not overriden
        if (!isset($mode))
        {
            // Return mode based on Apache server var
            if (isset($_SERVER[self::SERVER_VAR]))
                $mode = $_SERVER[self::SERVER_VAR];
            else
                throw new Exception('SetEnv YII_ENVIRONMENT <mode> not defined in Apache config.');
        }
 
        // Check if mode is valid
        if (!defined('self::' . $mode))
            throw new Exception('Invalid Environment mode');
 
        return $mode;
    }
 
    /**
     * Sets the environment and configuration for the chosen mode
     * @param constant $mode
     */
    private function setEnvironment()
    {
        // Load main config
        $configMainFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . self::MAIN_CONFIG;
        if (!file_exists($configMainFile))
            throw new Exception('Cannot find config file "' . $configMainFile . '".');
        require($configMainFile);
 
        // Load specific config
        $configFile = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'mode_' . strtolower($this->_mode) . '.php';
        if (!file_exists($configFile))
            throw new Exception('Cannot find config file "' . $configFile . '".');
        require($configFile);
 
        // Merge config arrays into one
        $this->_config = array_merge_recursive($config, $configSpecific);
 
        // Set other environment vars
        $this->_yiiPath = $yiiPath;
        $this->_debug = $debug;
        $this->_traceLevel = $traceLevel;
        $this->_config['params']['environment'] = constant('self::' . $this->_mode);
    }
 
    /**
     * Returns the path to the Yii framework
     * @return string
     */
    public function getYiiPath()
    {
        return $this->_yiiPath;
    }
 
    /**
     * Returns the debug mode for YII_DEBUG
     * @return Bool
     */
    public function getDebug()
    {
        return $this->_debug;
    }
 
    /**
     * Returns the trace level for YII_TRACE_LEVEL
     * @return int
     */
    public function getTraceLevel()
    {
        return $this->_traceLevel;
    }
 
    /**
     * Returns the configuration array
     * @return array
     */
    public function getConfig()
    {
        return $this->_config;
    }
 
}

index.php

<?php
 
// set environment
require_once(dirname(__FILE__) . '/protected/config/Environment.php');
$env = new Environment();
//$env = new Environment('PRODUCTION'); //override
 
// set debug and trace level
defined('YII_DEBUG') or define('YII_DEBUG', $env->getDebug());
defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', $env->getTraceLevel());
 
// run Yii app
require_once($env->getYiiPath());
Yii::createWebApplication($env->getConfig())->run();

protected/config/main.php

<?php
 
/**
 * Main configuration
 * This file should contain $yiiPath, $debug, $traceLevel and $config
 * These properties can be overridden or merged in mode_<mode>.php files
 */
 
 
// Set yiiPath (add extra ../../)
$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 
// Set YII_DEBUG and YII_TRACE_LEVEL flags
$debug = true;
$traceLevel = 0;
 
// Set config array
$config = array(
 
    'basePath' => dirname(__FILE__) . DIRECTORY_SEPARATOR . '..',
    'name' => 'My Application'
 
    // Preloading 'log' component
    'preload' => array('log'),
 
    // Autoloading model and component classes
    'import' => array(
        'application.models.*',
        'application.components.*',
    ),
 
    // Application components
    'components' => array(
 
        // User
        'user' => array(
            // enable cookie-based authentication
            'allowAutoLogin' => true,
        ),
 
        // uncomment the following to enable URLs in path-format
        /*
          'urlManager' => array(
            'urlFormat' => 'path',
            'rules' => array(
                '<controller:\w+>/<id:\d+>' => '<controller>/view',
                '<controller:\w+>/<action:\w+>/<id:\d+>' => '<controller>/<action>',
                '<controller:\w+>/<action:\w+>' => '<controller>/<action>',
            ),
        ),
        */
 
        // Error handler
        'errorHandler' => array(
            'errorAction' => 'site/error',
        ),
 
        // Database
        'db' => array(
            'connectionString' => '', //override in config/mode_<mode>.php
            'emulatePrepare' => true,
            'username' => '', //override in config/mode_<mode>.php
            'password' => '', //override in config/mode_<mode>.php
            'charset' => 'utf8',
        ),
 
    ),
 
    // Application-level parameters that can be accessed using Yii::app()->params['paramName']
    'params' => array(
        'adminEmail' => 'admin@example.com',
    ),
 
);

protected/config/mode_development.php:

<?php
 
/**
 * Development configuration
 * Usage:
 * - Local website
 * - Local DB
 * - Show all details on each error.
 * - Gii module enabled
 */
 
 
// Set yiiPath (add extra ../../)
//$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 
// Set YII_DEBUG and YII_TRACE_LEVEL flags
$debug = true;
$traceLevel = 3;
 
 
// Set specific config
$configSpecific = array(
 
    // Modules
    'modules' => array(
        'gii' => array(
            'class' => 'system.gii.GiiModule',
            'password' => 'password',
        ),
    ),
 
    // Application components
    'components' => array(
 
        // Database
        'db' => array(
            'connectionString' => 'mysql:host=localhost;dbname=example',
            'username' => 'root',
            'password' => '',
        ),
 
        // Application Log
        'log' => array(
            'class' => 'CLogRouter',
            'routes' => array(
                // Save log messages on file
                array(
                    'class' => 'CFileLogRoute',
                    'levels' => 'error, warning, trace, info',
                ),
                // Show log messages on web pages
                array(
                    'class' => 'CWebLogRoute',
                    //'categories' => 'system.db.CDbCommand',
                    'levels' => 'error, warning, trace, info',
                    //'showInFireBug' => true,
                ),
            ),
        ),
 
    ),
 
);

protected/config/mode_test.php:

<?php
 
/**
 * Test configuration
 * Usage:
 * - Local website
 * - Local DB
 * - Standard production error pages (404, 500, etc.)
 */
 
 
// Set yiiPath (add extra ../../)
//$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 
// Set YII_DEBUG and YII_TRACE_LEVEL flags
$debug = false;
$traceLevel = 0;
 
 
// Set specific config
$configSpecific = array(
 
    // Application components
    'components' => array(
 
        // Database
        'db' => array(
            'connectionString' => 'mysql:host=localhost;dbname=example_test',
            'username' => 'root',
            'password' => '',
        ),
 
        // Fixture Manager for testing
        'fixture' => array(
            'class' => 'system.test.CDbFixtureManager',
        ),
 
        // Application Log
        'log' => array(
            'class' => 'CLogRouter',
            'routes' => array(
                // Save log messages on file
                array(
                    'class' => 'CFileLogRoute',
                    'levels' => 'error, warning, trace, info',
                ),
                // Show log messages on web pages
                array(
                    'class' => 'CWebLogRoute',
                    //'categories' => 'system.db.CDbCommand',
                    'levels' => 'error, warning',
                ),
            ),
        ),
 
    ),
 
);

protected/config/mode_stage.php:

<?php
 
/**
 * Stage configuration
 * Usage:
 * - Online website
 * - Production DB
 * - All details on error
 */
 
 
// Set yiiPath (add extra ../../)
//$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 
// Set YII_DEBUG and YII_TRACE_LEVEL flags
$debug = true;
$traceLevel = 0;
 
 
// Set specific config
$configSpecific = array(
 
    // Application components
    'components' => array(
 
        // Database
        'db' => array(
            'connectionString' => 'mysql:host=STAGING_HOST;dbname=STAGING_DBNAME',
            'username' => 'USERNAME',
            'password' => 'PASSWORD',
        ),
 
        // Application Log
        'log' => array(
            'class' => 'CLogRouter',
            'routes' => array(
                // Save log messages on file
                array(
                    'class' => 'CFileLogRoute',
                    'levels' => 'error, warning, trace, info',
                ),
            ),
        ),
 
    ),
 
);

protected/config/mode_production.php:

<?php
 
/**
 * Production configuration
 * Usage:
 * - online website
 * - Production DB
 * - Standard production error pages (404,500, etc.)
 */
 
 
// Set yiiPath (add extra ../../)
//$yiiPath = dirname(__FILE__) . '/../../../yii/framework/yii.php';
 
// Set YII_DEBUG and YII_TRACE_LEVEL flags
$debug = false;
$traceLevel = 0;
 
 
// Set specific config
$configSpecific = array(
 
    // Application components
    'components' => array(
 
        // Database
        'db' => array(
            'connectionString' => 'mysql:host=PRODUCTION_HOST;dbname=PRODUCTION_DBNAME',
            'username' => 'USERNAME',
            'password' => 'PASSWORD',
        ),
 
        // Application Log
        'log' => array(
            'class' => 'CLogRouter',
            'routes' => array(
                // Save log messages on file
                array(
                    'class' => 'CFileLogRoute',
                    'levels' => 'error, warning, trace, info',
                ),
                // Send errors via email to the system admin
                array(
                    'class' => 'CEmailLogRoute',
                    'levels' => 'error, warning',
                    'emails' => 'marco@example.com',
                ),
            ),
        ),
 
    ),
 
);
#131 report it
cma at 2010/08/31 11:01am
Another solution to keep your config files

It's a great class, but I prefer to see the passwords in separated files.

/**
This class helps you to configured your Yii application environment.
   * The configs array are on separeted file as described in documentation. 
   * This let you the ability of hidding files, avoid modification, ect
   * The switch between environnement can be done via http.conf SetEnv directive
   * The switch between environnement can be done via http.conf SetEnv directive
   * Inspired by nancoder @see http://www.yiiframework.com/doc/cookbook/73
   * 
   * Customize : 
   * - env. settings & supported ( MODE_xxx, YII_PATH_xxx const ) 
   * - customize {@link _setCustomFlags()} & {@link _setYiiPath()} to fit your environnement
   * use this class like this in the bootstrap (index.php)
   * <pre>
   *     require_once(dirname(__FILE__).'/protected/config/environment.php');
   *     $environment = new Environment() ;
   *     
   *     defined('YII_DEBUG') or define( 'YII_DEBUG' , $environment->debug );
   *     defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', $environment->traceLevel );
   *     
   *     $environment->processRequire();
   *     
   *     Yii::createWebApplication( $environment->config )->run();
   * </pre>
   * @name Environment
   * @author Christophe Marti - i-axes SA
   * @version 1.0
   * @property string mode the current mode
   * @property boolean debug the debug flag
   * @property integer traceLevel the trace level
   * @property mixed config the config to use
   */
  class Environment
  {
 
    //********** environnement settings
 
    /**
     * @var string http.conf variable
     */
    const SERVER_ENV = 'APPLIC_ENVIRON';
 
 
    /**
     * @var string use in $this->_setYiiPath() to find the great in dev
     */  
    const PATH_YII_DEV = '/../../../../dev-data/yii-1.1.3.r2247/framework/yii.php';
 
 
    /**
     * @var string use in $this->_setYiiPath() to find the great in prod-valid
     */  
    const PATH_YII_PROD = '/../../../../libs/yii-1.1.3.r2247/framework/yii.php';
 
 
    /**
     * @var string use in constructor to create the full path to the config to be loaded
     */
    const BASE_CONFIG_NAME = 'main-';
 
 
    /**
     * @var string use in constructor to create the full path to the config to be loaded
     */
    const BASE_CONFIG_NAME_EXT = '.php';
 
 
    //********** environnement supported
    /**
     * @var string a self::BASE_CONFIG_NAME . self::MODE_DEV . self::BASE_CONFIG_NAME_EXT should exist in the same folder
     */
    const MODE_DEV = 'dev';
 
    /**
     * @var string @see self::MODE_DEV
     */
    const MODE_DEV_LOCAL = 'dev-local';
 
 
    /**
     * @var string  @see self::MODE_DEV
     */  
    const MODE_VALID = 'valid';
 
 
    /**
     * @var string  @see self::MODE_DEV
     */  
    const MODE_PROD = 'prod';
 
 
    //********** array key used in $this_current to store values
 
    /**
     * @var string key for the choosen environnement ($this->_current key)
     */  
    const KEY_ENV = "environ";
 
 
    /**
     * @var string key for the debug flag ($this->_current key)
     */  
    const KEY_DEBUG = "debug";
 
 
    /**
     * @var string key for the trace level ($this->_current key)
     */  
    const KEY_TRACE = "trace";
 
 
    /**
     * @var string key for the loaded configuration ($this->_current key)
     */  
    const KEY_CONFIG = "config";
 
 
    /**
     * @var string key for the loaded configuration ($this->_current key)
     */  
    const KEY_YII = "yiipath";
 
 
    /**
     * @var mixed choosen configuration information
     */
    private $_current = array();
 
 
    /**
     * Initialize the environnement
     * @param string $environnement the mode to use, see self::MODE_xxx. If unspecified try to load from httpd.conf
     */
    function __construct ( $environnement = '' )
    {
      if ( empty( $environnement ) ) 
        if ( array_key_exists( self::SERVER_ENV , $_SERVER ) ) 
          $environnement = $_SERVER[ self::SERVER_ENV ]; //try to get the running mode from apache conf
        else
          throw new Exception( '"SetEnv '.self::SERVER_ENV.' xxx" isn\'t defined in Apache configs!' );
 
      $this->_current[ self::KEY_ENV ] = $environnement;
 
      if ( empty( $this->_current[ self::KEY_ENV ] ) ) 
        throw new Exception( "Unable to get configuration mode!" );
 
      $config_filepath = dirname( __FILE__ ) .DIRECTORY_SEPARATOR . 
        self::BASE_CONFIG_NAME . $this->_current[ self::KEY_ENV ] . self::BASE_CONFIG_NAME_EXT;
 
      if ( ! file_exists( $config_filepath ) ) 
        throw new Exception( "The configuration file '$config_filepath' doesn't exist !" );
 
      //load the config 
      $this->_current[ self::KEY_CONFIG ] = $config_filepath;
 
      $this->_setCustomFlags();
      $this->_setYiiPath();
    }
 
 
    /**
     * Magic getter for environnement values
     * @param string $key the getter
     * @return mixed the value contained by $this->_current[$key]
     */
    public function __get( $key )
    {
      if ( array_key_exists( strtolower( $key ) , $this->_current ) )      
        return $this->_current[ $key ];
    }
 
 
    /**
     * Sets the configuration flags for the choosen enviroment
     * @return nothing $this->_current[trace & debug] are defined
     */
    private function _setCustomFlags ()
    {
      switch ( $this->_current[ self::KEY_ENV ] )
      {
        case self::MODE_DEV :
        case self::MODE_DEV_LOCAL :
          $this->_current[ self::KEY_DEBUG ] = true;
          $this->_current[ self::KEY_TRACE ] = 3;
          break;
 
        default :
          $this->_current[ self::KEY_DEBUG ] = false;
          $this->_current[ self::KEY_TRACE ] = 0;
          break;
      }
    }
 
    /**
     * Sets the configuration flags for the choosen enviroment
     * @return nothing $this->_current[trace & debug] are defined
     */
    private function _setYiiPath()
    {
      switch ( $this->_current[ self::KEY_ENV ] )
      {
        case self::MODE_DEV :
        case self::MODE_DEV_LOCAL :
          $this->_current[ self::KEY_YII ] = dirname(__FILE__) . self::PATH_YII_DEV;
          break;
 
        case self::MODE_PROD :
        case self::MODE_VALID :
          $this->_current[ self::KEY_YII ] = dirname(__FILE__). self::PATH_YII_PROD;
          break;
      }    
    }  
 
 
    /**
     * Load Yii & globals.php
     */
    public function processRequire()
    {
      //some globals functions
      $globals = dirname(__FILE__)  . '/../globals.php';
      require_once ( $globals );
 
      require_once( $this->_current[ self::KEY_YII ] );
    }
  }

Usage

The usage is the same as nancoder class, in index.php

require_once(dirname(__FILE__).'/protected/config/environment.php');
    $environment = new Environment() ;
 
    defined('YII_DEBUG') or define( 'YII_DEBUG' , $environment->debug );
    defined('YII_TRACE_LEVEL') or define('YII_TRACE_LEVEL', $environment->traceLevel );
 
    $environment->processRequire();
 
    Yii::createWebApplication( $environment->config )->run();
#332 report it
tommytwoeyes at 2010/07/06 04:24pm
Excellent idea

I really like this class. Great idea!

You could (if desirable) automate it a little further by letting the application set its own environment dynamically based on the application's path.

For instance, I have my application installed in a certain path like '/home/me/sites/my_application' on my development machine, and something like '/var/apps/live_application' on my production box, so you could use something like this in your index.php file:

$env = ( stristr( dirname(__FILE__), '/home/me' ) ? 
    new Environment(Environment::DEVELOPMENT) : 
    new Environment(Environment::PRODUCTION);

Leave a comment

Please to leave your comment.

Write new article
  • Written by: nancoder
  • Updated by: marcovtwout
  • Category: Tutorials
  • Yii Version: 1.1
  • Votes: +6
  • Viewed: 21,230 times
  • Created on: Jun 16, 2010
  • Last updated: Mar 11, 2011