{"id":295,"date":"2012-09-15T15:05:38","date_gmt":"2012-09-15T14:05:38","guid":{"rendered":"http:\/\/www.cotsweb.com\/blog\/?p=295"},"modified":"2014-02-15T14:56:20","modified_gmt":"2014-02-15T14:56:20","slug":"using-ifdefine-in-htaccess-file-to-allow-different-environments-in-apache","status":"publish","type":"post","link":"https:\/\/www.cotsweb.com\/blog\/using-ifdefine-in-htaccess-file-to-allow-different-environments-in-apache-295.html","title":{"rendered":"Using IfDefine in .htaccess file to support different environments in Apache"},"content":{"rendered":"<p>I have three environments for most of the websites I build or support.<\/p>\n<ol>\n<li>My development machine where I do all the coding and initial testing. \u00a0Windows XP running Apache as part of \u00a0a\u00a0 XAMPP setup. \u00a0All my local domain names are called something like &#8220;local.example.com&#8221;<\/li>\n<li>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. \u00a0Ubuntu server running Apache. \u00a0All the domain names are called something like &#8220;staging.example.com&#8221;<\/li>\n<li>The live webserver which is run by Hostgator in Texas. \u00a0Apache again and of course the domain names are something like &#8220;example.com&#8221;.<\/li>\n<\/ol>\n<p>I use Git to manage the code and to push changes from one environment to another.<\/p>\n<p>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&#8217;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.<\/p>\n<h2>Configuration in PHP<\/h2>\n<p>It isn&#8217;t difficult to do this with a PHP module, I just use a switch statement on the value of $_SERVER[&#8216;SERVER_NAME&#8217;] 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&#8217;t damage the live site. \u00a0Something like this;<br \/>\n<pre><code class=\"preserve-code-formatting\">switch ($_SERVER[&#039;SERVER_NAME&#039;]) {\ncase &#039;local.example.com:\n$environment = &#039;local&#039;;\nbreak;\ncase &#039;staging.example.com:\n$environment = &#039;staging&#039;;\nbreak;\ndefault:\n$environment = &#039;live&#039;;\nbreak;\n}\n<\/code><\/pre><\/p>\n<h2>Configuration in .htaccess<\/h2>\n<p>Apache&#8217;s .htaccess files are a bit more complicated. \u00a0For 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.\u00a0 To do this I added the following code to the .htaccess file;<br \/>\n<pre><code class=\"preserve-code-formatting\">\n#\n# Use PHP 5.3 rather than default of 5.2\n#\nAddType application\/x-httpd-php53 .php\n#\n# Until we are ready to go live this site is password protected\n#\nAuthType Basic\nAuthName &quot;New website&quot;\nAuthUserFile &quot;\/home\/username\/.htpasswds\/public_html\/passwd&quot;\nrequire valid-user\n\n<\/code><\/pre><br \/>\nThe block is only executed if Apache hasn&#8217;t been started with the DEV variable set. So in my case it will only be executed in the production evironment.<\/p>\n<h2>Defining an Apache Environment Variable in Windows<\/h2>\n<p>The tricky bit is getting the environment variable set up in my development and testing environments. Fortunately I found <a title=\"Using IfDefine Conditions in an Apache .htaccess file\" href=\"http:\/\/stackoverflow.com\/questions\/11073752\/apache-ifdefine-conditionals-in-htaccess\">a useful post by Nerivon on StackOverFlow<\/a>, it saved me a lot of messing around. I had to tweak Nerivon&#8217;s technique slightly for XAMPP but it worked perfectly.<\/p>\n<ol>\n<li>First I stopped Apache<\/li>\n<li>Then I went into SCM from the XAMPP control panel, this opens the Windows Services Management Console<\/li>\n<li>I found the Apache2.2 service and checked out it&#8217;s properties. Specifically I wanted the &#8220;Path to executable&#8221; value.<code class=\"preserve-code-formatting\">&quot;C:\\xampp\\apache\\bin\\httpd.exe&quot; -k runservice<\/code><\/li>\n<li>Then I opened a command window with RUN \/ CMD so I got a DOS prompt.<\/li>\n<li>In that window I entered this command; <code class=\"preserve-code-formatting\">&quot;C:\\xampp\\apache\\bin\\httpd.exe&quot; -D &quot;DEV&quot; -k config<\/code>That is the &#8220;path to executable&#8221; from above but an extra parameter &#8220;-D DEV&#8221; which defines my new DEV variable and with the last parameter &#8220;runservice&#8221; replaced with &#8220;config&#8221;<\/li>\n<li>Then I restarted Apache and tested the change, it worked!<\/li>\n<\/ol>\n<p>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&#8217;t find it in the registry either. I don&#8217;t know how it works but it does seem to do the job.<\/p>\n<h3>Caveat<\/h3>\n<p>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&#8217;t a perfect solution.<br \/>\nIf anyone has a better solution I&#8217;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.<\/p>\n<h2>Defining an Apache Environment Variable in Linux<\/h2>\n<p>Unsurprisingly setting my DEV variable up on the Linux server was a lot simpler. Again I found help on the web, <a title=\"Using IfDefine in Apache on linux\" href=\"http:\/\/jennyandlih.com\/using-apaches-ifdefine-dev-and-production-environments\">Jenny and Lih had useful article about using IfDefine for different environments<\/a>.<br \/>\nI edited \/etc\/apache2\/envvars and added the following line to the end of the file;<br \/>\n<code class=\"preserve-code-formatting\">export APACHE_ARGUMENTS=&#039;-D DEV&#039;<\/code><\/p>\n<p>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.<\/p>\n<p>I stopped and restarted Apache and tested the site, it worked! \u00a0But be aware that a simple reload isn&#8217;t sufficient, you o need to stop and start it to load the new argument.<\/p>\n<h2>All Done<\/h2>\n<p>Both my local environments set the DEV variable so my block of code would be ignored there whereas the live environment doesn&#8217;t set it so executes the extra code. Perfect.<br \/>\nI could have set up different variables for the different environments but I don&#8217;t need to at present so I have taken the simple option of just setting and checking one variable.<\/p>\n<p>&nbsp;<\/p>\n<!-- AddThis Advanced Settings generic via filter on the_content --><!-- AddThis Share Buttons generic via filter on the_content -->","protected":false},"excerpt":{"rendered":"<p>I have three environments for most of the websites I build or support. My development machine where I do all the coding and initial testing. \u00a0Windows XP running Apache as part of \u00a0a\u00a0 XAMPP setup. \u00a0All my local domain names are called something like &#8220;local.example.com&#8221; My testing machine which is designed to be as similar [&hellip;]<!-- AddThis Advanced Settings generic via filter on get_the_excerpt --><!-- AddThis Share Buttons generic via filter on get_the_excerpt --><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[123,19,18],"tags":[124,127,126,145,125],"_links":{"self":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts\/295"}],"collection":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/comments?post=295"}],"version-history":[{"count":29,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts\/295\/revisions"}],"predecessor-version":[{"id":322,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/posts\/295\/revisions\/322"}],"wp:attachment":[{"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/media?parent=295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/categories?post=295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.cotsweb.com\/blog\/wp-json\/wp\/v2\/tags?post=295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}