I’ve recently been getting to grips with the Codeigniter framework after years of using a home-grown monstrosity. I was becoming more and more concerned about the level of security in my own framework and decided I would be better off with something that’s maintained.
I researched the many PHP frameworks to find one that was going to work for me. I toyed with the idea of using Symfony, which is what our products are based on, but the time to get up-to-speed with it was greater than I wanted to invest. I therefore settled on Codeigniter which looked easier to get started with while still offering a lot the scaffolding I knew I needed.
I’m currently in the process of rewriting PostRecycler to use CodeIgniter and it has been pretty swift and straightforward. One thing that threw me for quite a while though was getting the environments to work across all platforms and domains.
By default the environment setting (which you can find in index.php in the root of your project) is simply the following:
define('ENVIRONMENT', isset($_SERVER['CI_ENV']) ? $_SERVER['CI_ENV'] : 'development');
This is straightforward enough but gives no flexibility at all so I set about crafting the perfect environment setter which is below. None of this is completely original. Some comes from Lonnie Ezell’s excellent book Practical Codeigniter 3, some from other blogs and other bits I added.
The code starts by setting an array with all the domains that you are using and assigning them an environment. This is taken from Lonnie’s book. The difference here is in the handling of CLI calls. My app has both web and command line controllers so it was important that it should be able to handle both.
Unlike when being called from the browser where you can infer the environment from the domain name with the CLI you need to tell it. This is done as follows:
php index.php controller index --env development
By checking php_sapi_name() you can see if the controller is being called from the command line. Then grab the arguments and look for ‘–env’ taking the following one as the environment.
My change is to firstly bring these two approaches together (browser and CLI environment setting) along with setting a default environment for CLI in case the parameters aren’t passed. Like calling from the WWW this defaults to setting the environment as production, the safest option to take. The final code is as follows:
$domains = array( 'application.local' => 'development', 'beta.application.com' => 'testing', 'www.application.com' => 'production', 'application.com' => 'production' ); if (php_sapi_name() === 'cli') { if (isset($argv)){ // grab the --env argument, and the one that comes next $key = (array_search('--env', $argv)); if (empty($key)){ define('ENVIRONMENT', 'production'); }else{ $environment = $argv[$key +1]; define('ENVIRONMENT', $environment); // get rid of them so they don't get passed in to our method as parameter values unset($argv[$key], $argv[$key +1]); } }else{ define('ENVIRONMENT', 'development'); } }else{ // Have we defined a server for this host? if ( ! empty($domains[$_SERVER['HTTP_HOST']])) { define('ENVIRONMENT', $domains[$_SERVER['HTTP_HOST']]); } // Or is it a development machine, like myapp.dev? else if (strpos($_SERVER['HTTP_HOST'], '.local') !== FALSE) { define('ENVIRONMENT', 'development'); } // Else - be safe... else { define('ENVIRONMENT', 'production'); } }
Hopefully you will find the code useful and save you some time.