Switching server environments
After reading John Rockefeller’s post on Handling multiple domains and less recently Richard Heye’s post on displaying errors, I thought I’d write a little post about my qualms with their methods.
I won’t go into too much detail, but both examples use a variable that can be manipulated by the user, $_SERVER['HTTP_HOST']. Richard actually changed his example to use $_SERVER['SERVER_NAME'], but as Chris Shiflett shows, neither are guaranteed to be genuine.
My example relies on having access to the server configuration, but is fairly simple. I think Ruby on Rails uses a similar method.
First we set up our virtual hosts, all pointing to the same codebase, but each getting an individual environment variable set using mod_env.
<VirtualHost *:80>
ServerName davedevelopment.co.uk
DocumentRoot /var/www/codebase
SetEnv WEB_ENV davedevelopment.co.uk
</VirtualHost>
<VirtualHost *:80>
ServerName test.davedevelopment.co.uk
DocumentRoot /var/www/codebase
SetEnv WEB_ENV test.davedevelopment.co.uk
</VirtualHost>
<VirtualHost *:80>
ServerName anotherSite.com
DocumentRoot /var/www/codebase
SetEnv WEB_ENV another_site
</VirtualHost>
The code then switches on this variable, which should be guaranteed to be controlled by yourself?
<?php
switch($_SERVER['WEB_ENV']) {
case 'davedevelopment.co.uk':
$message = 'Welcome to DaveDevelopment';
break;
case 'another_site':
$message = 'Welcome to another site';
break;
case 'test.davedevelopment.co.uk':
default:
$message = 'Welcome to DaveDevelopment Test';
break;
}
echo $message;
?>
Popularity: 72% [?]
Tags: Apache, environment, PHP
May 26th, 2008 at 5:03 pm
Hi Dave
Thanks for taking the time to provide an alternate method to switching code based on domains. I am curious, is there any way to safely do this for those of us without access to mod_env or the apache config? Say for shared hosting or something of that sort?
May 26th, 2008 at 7:28 pm
As long as you code defensively enough, the method you outlined should be secure.
In your little example, you use an If … Else If construct. If you were to continue that block and have an Else block at the bottom, this could be a catch all, effectively your default site.
I think the real danger with these variables is when people start doing this type of thing.
<a href=”<?php echo $_SERVER['SERVER_NAME'];? rel=”nofollow”>/dave.php”>Dave</a>
They think they don’t need to escape $_SERVER['SERVER_NAME'] because they think it’s safe.
May 27th, 2008 at 8:54 am
For those who don’t have access to the httpd.conf, most hosts allow the SetEnv in the .htaccess. If yours doesn’t, it’s probably time to switch !
May 27th, 2008 at 9:38 am
Very informative :) Thanks for having blog like this. keep up the good work :)
May 29th, 2008 at 11:22 am
That’s an interesting way of dealing with multiple environments, not one I would have thought of!
I notice that you use phing as a build engine - I use phing to rewrite a constant env variable in a config file. This is useful if deploying the same code to several machines at once.
May 29th, 2008 at 1:04 pm
@Chris:
We use a similar method at work, but only for application configuration, we don’t really have environment modes. The other thing I like about doing it this way is the application reads it’s config through regular constants, good for optimisation, no real need to cache settings etc., but developers and admins actually configure the application using an ini file.
May 29th, 2008 at 1:06 pm
@Chris:
Just followed your URL, good to see some more PHP guys flying the flag for Hull!
August 20th, 2008 at 12:29 am
Just wondering if you have any data on which one is faster, yours or mine?
August 21st, 2008 at 10:13 am
No idea, I can’t imagine there being much difference, except maybe my method requires an extra few bytes of memory for the environment variable.