My name is  
Jurgens du Toit.
Systems Developer.
Problem Solver.

About Me

Technology and Solving Problems are my passion. I'm a South African that loves my wife, life, and coding.

I'm writing a book!

The Logstash Config Guide

Buy it now on Leanpub

13 September 2011

A PHP Virtual Host

By Jurgens du Toit

I hate repetitive work. I love solving a puzzle. So it often happens that I’d spend 2 hours writing a script to solve a repetitive problem, than just taking the 2 minutes to do it manually. Creating apache config files are tedious and boring, so I wrote a PHP script that emulates Virtual Hosting.

You can get the code on GitHub. A Warning: The code is not production ready. Use it at your own risk. Here’s what it does:

An .htaccess file redirects all requests to the index.php file, which sits in /var/www. We get the host from the $_SERVER variable, and check if a folder for that host exists.

1
2
3
4
5
6
7
8
<?php
$host   = $_SERVER['HTTP_HOST'];
$folder = getcwd() . '/' . $host . '/';
if (!file_exists($folder)) {
no_host();
die;
}
?>

So if we wanted to server jrgns.net from it, the folder /var/www/jrgns.net should exist on the server. If it doesn’t, a generic message is displayed.

Courtesy of the .htaccess file, the whole URL, except the host name, gets passed to the script in the f query variable. As we might be requesting a stylesheet such as jrgns.net/styles/basic.css, the virtual host should pick that up. If no file is requested, check for and serve an index file.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
<?php
if (empty($_REQUEST['f'])) {
	$indexes = array(
		'index.php', 'index.html', 'index.htm', 'main.php'
	);
	foreach($indexes as $index) {
		if (file_exists($folder . $index)) {
			chdir($folder);
			include($folder . $index);
			die;
		}
	}
} else {
	$file = $_REQUEST['f'];
	if (file_exists($folder . $file)) {
		$info = explode('.', $file);
		switch(end($info)) {
		case 'js':
			header('Content-Type: text/javascript');
			break;
		case 'css':
			header('Content-Type: text/css');
			break;
		}
		readfile($folder . $file);
		die;
	}
}
?>

I use a very rudimentary way to get the file extension, and then send the content header. There are probably better ways to do this, but it works. The rest is just the generic message that gets displayed if we don’t know what you’re looking for.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
    <?php
    function no_host() {
    	global $host;
    ?><!DOCTYPE html>
    <html>
    	<head>
    		<title>Unknown Domain: <?php echo $host ?></title>
    	</head>
    	<body>
    		<div>
    			<h1>Unknown Domain: <?php echo $host ?></h1>
    		</div>
    	</body>
    </html>
    
    <?php
    }
    no_host();
    ?>

Like I said. Simple!

blog comments powered by Disqus