Create subdomains on the fly with .htaccess (PHP)

Solution 1:

The quick rundown

  1. You need to create a wildcard domain on your DNS server *.website.com
  2. Then in your vhost container you will need to specify the wildcard as well *.website.com - This is done in the ServerAlias DOCs
  3. Then extract and verify the subdomain in PHP and display the appropriate data

The long version

1. Create a wildcard DNS entry

In your DNS settings you need to create a wildcard domain entry such as *.example.org. A wildcard entry looks like this:

*.example.org.   3600  A  127.0.0.1

2. Include the wildcard in vhost

Next up in the Apache configuration you need to set up a vhost container that specifies the wildcard in the ServerAlias DOCs directive. An example vhost container:

<VirtualHost *:80>
  ServerName server.example.org
  ServerAlias *.example.org
  UseCanonicalName Off
</VirtualHost>

3. Work out which subdomain you are on in PHP

Then in your PHP scripts you can find out the domain by looking in the $_SERVER super global variable. Here is an example of grabbing the subdomain in PHP:

preg_match('/([^.]+)\.example\.org/', $_SERVER['SERVER_NAME'], $matches);
if(isset($matches[1])) {
    $subdomain = $matches[1];
}

I have used regex here to to allow for people hitting your site via www.subdomain.example.org or subdomain.example.org.

If you never anticipate having to deal with www. (or other subdomains) then you could simply use a substring like so:

$subdomain = substr(
                 $_SERVER['SERVER_NAME'], 0,
                 strpos($_SERVER['SERVER_NAME'], '.')
             );

Mass Virtual Hosting

Mass virtual hosting is a slightly different scheme to the above in that you would usually use it to host many distinct websites rather than attempting to use it power an application as the question proposes.

I have documented my mod_rewrite based mass virtual hosting environment before in a post on my blog, which you could look at if that is the route you wish to take. There is also, of course, the respective Apache manual page.

Apache also has an internal way of dealing with mass virtual hosting that is slightly less flexible than the mod_rewrite method I have used. This is all described on the Apache Dynamically Configured Mass Virtual Hosting manual page.

Solution 2:

You could allow every subdomain in the first place and then check if the subdomain is valid. For example:

RewriteEngine on
RewriteCond %{HTTP_HOST} ^[^.]+\.example\.com$
RewriteRule !^index\.php$ index.php [L]

Inside the index.php you can than extract the subdomain using:

if (preg_match('/^([^.]+)\.example\.com$/', $_SERVER['HTTP_HOST'], $match)) {
    var_dump($match[1]);
}

But all this requires that your webserver accepts every subdomain name.

Solution 3:

In addition to setting up a DNS wildcard, you might want to take a look at Dynamic Mass Virtual Hosting for Apache which is how I've solved this in the past

Solution 4:

The easiest way is to redirect all subdomains (with wildcard *) to point to your /wwwroot. Then put .htaccess to this folder with the following code:

RewriteCond %{ENV:REDIRECT_SUBDOMAIN} ="" 
RewriteCond %{HTTP_HOST} ^([a-z0-9][-a-z0-9]+)\.domain\.com\.?(:80)?$ [NC] 
RewriteCond %{DOCUMENT_ROOT}/%1 -d 
RewriteRule ^(.*) %1/$1 [E=SUBDOMAIN:%1,L] 
RewriteRule ^ - [E=SUBDOMAIN:%{ENV:REDIRECT_SUBDOMAIN},L]

This will accomplish that every subfolder of the /wwwroot folder in acceptable via subdomain (foldername.domain.com).

Found this years ago on http://www.webmasterworld.com/apache/3163397.htm