Posts Tagged ‘PHP’

Using IfDefine in .htaccess file to support different environments in Apache

Saturday, September 15th, 2012

I have three environments for most of the websites I build or support.

  1. My development machine where I do all the coding and initial testing.  Windows XP running Apache as part of  a  XAMPP setup.  All my local domain names are called something like “local.example.com”
  2. My testing machine which is designed to be as similar as possible to the live setup, I can access the server from other machines on the LAN to enable testing in different browsers.  Ubuntu server running Apache.  All the domain names are called something like “staging.example.com”
  3. The live webserver which is run by Hostgator in Texas.  Apache again and of course the domain names are something like “example.com”.

I use Git to manage the code and to push changes from one environment to another.

Different environments often require slightly different configurations but I prefer to put conditional statements in my configuration files so that the same file works in all environments. That way I don’t have to modify the configuration before promoting it to production. It is just too easy to accidentally push a development module to production and overwrite the correct configuration on the live site.

Configuration in PHP

It isn’t difficult to do this with a PHP module, I just use a switch statement on the value of $_SERVER[‘SERVER_NAME’] and use this to define the various configuration variables. The default value is always the production settings so if I get something wrong I don’t damage the live site.  Something like this;

switch ($_SERVER['SERVER_NAME']) {
case 'local.example.com:
$environment = 'local';
break;
case 'staging.example.com:
$environment = 'staging';
break;
default:
$environment = 'live';
break;
}

Configuration in .htaccess

Apache’s .htaccess files are a bit more complicated.  For instance Hostgator requires you to specify if you want to use PHP 5.3 rather than their default of 5.2, also I sometimes want to password protect a new site until it is ready for its proper debut.  To do this I added the following code to the .htaccess file;


#
# Use PHP 5.3 rather than default of 5.2
#
AddType application/x-httpd-php53 .php
#
# Until we are ready to go live this site is password protected
#
AuthType Basic
AuthName "New website"
AuthUserFile "/home/username/.htpasswds/public_html/passwd"
require valid-user


The block is only executed if Apache hasn’t been started with the DEV variable set. So in my case it will only be executed in the production evironment.

Defining an Apache Environment Variable in Windows

The tricky bit is getting the environment variable set up in my development and testing environments. Fortunately I found a useful post by Nerivon on StackOverFlow, it saved me a lot of messing around. I had to tweak Nerivon’s technique slightly for XAMPP but it worked perfectly.

  1. First I stopped Apache
  2. Then I went into SCM from the XAMPP control panel, this opens the Windows Services Management Console
  3. I found the Apache2.2 service and checked out it’s properties. Specifically I wanted the “Path to executable” value."C:\xampp\apache\bin\httpd.exe" -k runservice
  4. Then I opened a command window with RUN / CMD so I got a DOS prompt.
  5. In that window I entered this command; "C:\xampp\apache\bin\httpd.exe" -D "DEV" -k configThat is the “path to executable” from above but an extra parameter “-D DEV” which defines my new DEV variable and with the last parameter “runservice” replaced with “config”
  6. Then I restarted Apache and tested the change, it worked!

Oddly when I look at the properties in SCM they are exactly the same as they were, no sign of the extra parameter, and I can’t find it in the registry either. I don’t know how it works but it does seem to do the job.

Caveat

Well it worked ok for a few days then I made some changes to my Apache set-up and restarted it but normally, not as a service. It lost my environment variable! I was able to repeat the instructions above and restart the service again and all was well again but it looks like this isn’t a perfect solution.
If anyone has a better solution I’d like to hear it, in the meantime this will do but I will keep this blog entry handy to remind me what to do when it goes wrong again.

Defining an Apache Environment Variable in Linux

Unsurprisingly setting my DEV variable up on the Linux server was a lot simpler. Again I found help on the web, Jenny and Lih had useful article about using IfDefine for different environments.
I edited /etc/apache2/envvars and added the following line to the end of the file;
export APACHE_ARGUMENTS='-D DEV'

Update Feb 2014: In later versions of Apache the export APACHE_ARGUMENTS line already exists but has an empty value and is commented out; in this case just modify the line to match the line above.

I stopped and restarted Apache and tested the site, it worked!  But be aware that a simple reload isn’t sufficient, you o need to stop and start it to load the new argument.

All Done

Both my local environments set the DEV variable so my block of code would be ignored there whereas the live environment doesn’t set it so executes the extra code. Perfect.
I could have set up different variables for the different environments but I don’t need to at present so I have taken the simple option of just setting and checking one variable.