Subdomaining with Cake

By Mumtaz (Mum_Chamber)
In this article, following a practical approach to subdomaining, we will make one model available through subdomains. Can be inspiring for alternative uses.
Inspired by the Hosting Admin URLs on a Subdomain at http://bakery.cakephp.org/articles/view/hosting-admin-urls-on-a-subdomain, I have tried to come up with some piece of code that makes uses of subdomains in an elegant way.

The aim is to access all instances of a model through subdomains. For instance, every user may have their subdomains, accessible at username.example.com

In order to deal with this, I assume that you already made the necessary implementations in your controller. Some sample code would look like (user_controller.php) :
Download code function view($unique_title){
    $this->set('users', $this->User->findByUniqueTitle($unique_title) ); 
}

Also, you need to route your users model at app/config/routes.php with something like:

Download code Router::connect('/user/*', array('controller' => 'user', 'action' => 'view'));
Now, what we will actually do is run some piece of code before the MVC implementation is started. The correct place to do this is the app/config/bootsrap.php

bootstrap.php : Download code $subdomain = substr( env("HTTP_HOST"), 0, strpos(env("HTTP_HOST"), ".") );
if( strlen($subdomain)>0 && $subdomain != "www" ) {
    $_GET["url"] = "user/" . $subdomain . "/" . (isset($_GET["url"]) ? $_GET["url"] : "");
}

This piece of code is pretty self explanatory. if the subdomain is different than "www", the page displayed is users//. So, mumchamber.example.com/about is actually displaying the url www.example.com/users/mumchamber/about
To test subdomains on localhost, you may want to have a look at http://digitalpbk.blogspot.com/2007/01/making-subdomains-on-localhost.html Only remember that in linux, your hosts file is probably located at /etc/hosts

Also, you may want to see http://httpd.apache.org/docs/1.3/vhosts/ for virtual host documentation

 

Comments 614

CakePHP Team Comments Author Comments
 

Comment

1 maybe htaccess

Why don`t you use .htaccess?

RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?(([a-z0-9_-]{1,100})\.)?example\.com$
RewriteRule ^(.*)$ /users/%3/about [L]
Regards
Posted Feb 5, 2008 by MichaƂ Bachowski
 

Comment

2 Why not htaccess

Well, even though .htaccess is also a nice way of dealing with subdomains, my personal experience shows that it's not the best solution for this particular case. Usually, if you make a model accessible through subdomains, you want to have exceptions. For instance, you may want to perserve admin.example.com, docs.example.com, wiki.example.com for obvious purposes. In this case, .htaccess gives you less (not little, only less) flexibility. With this piece of code, you can very easily implement restrictions or apply changes.
Posted Feb 5, 2008 by Mumtaz
 

Comment

3 Thanks

This was very helpful - thanks! Though I did find people kept trying to access my site via http://www.username.example.com so I did:


    $url_parts = explode('.', env('HTTP_HOST'));
    foreach($url_parts as $part) {
        if(!in_array($part, array('www', 'example', 'com'))) {
            $ident = $part;

        }
    }
Posted Feb 19, 2008 by Brit Gardner
 

Comment

4 Nice idea for social sites

thanks for your code.
i think it will help me a lot on my 'blogging' project.
currently, i am working on a 'social bookmarking' project. will try to implement your code so that users bookmarks can be accessed from user.sitename.com ;)
Posted Feb 29, 2008 by Fahad Ibnay Heylaal
 

Comment

5 nice article

i have read another article from http://www.ipuh.org/items/view/48:how-to-add-subdomain-on-cakephp i have problem too with subdomain in cakephp.This article helpful.
Posted Mar 20, 2008 by budi allay
 

Question

6 Named parameters with this approach to subdomaining

I am using this method for subdomaining with cake and it works.

However, when I introduce named parameters - I immediately get a 403 Permission Denied from Apache. This is odd because if I directly access the controller/view/ in the URL even ith the named parameters it works fine.

Thus, I have set things up according to this article such that:
http://username.localhost/cakejunction/ essentially goes to:
http://localhost/cakejunction/partners/username/load/

Works great. However, If I add named parameters to the URL like this:
http://username.localhost/cakejunction/p1:page1/p2:value2 I immediately get a 403 - Permission Denied from Apache.

What is interesting, is if I use the direct equivalent URL that this would have translated into:
http://localhost/cakejunction/partners/username/load/p1:page1/p2:value2
It works fine.

So - I conclude that it is likely some combination of the subdomaining mechanism, the named parameters with colons and the Apache configuration.

WinXP
PHP5
Apache 2
Cake 1.2


Posted Aug 28, 2008 by Zack
 

Question

7 do I have to create subdomains individually

I understand how to create the subdomains for localhost but do I also have to create subdomains individually for my production installation. I would want to allow users to acces sites from a subdomain and therfore individually createing the subdomains would invlove some overhead.
Thanks
Posted Nov 24, 2008 by Will Speak
 

Comment

8 Use wildcard subdomain

If you register in DNS *.yourdomain.com , then you can access any random subdomains without needing to register them specifically. Just make sure your Apache is set up to handle this wildcard too.
Posted Nov 24, 2008 by Grant Cox.
 

Comment

9 my version

Here's my version:

preg_match('/^(?:www\.)?(?:(.+)\.)?(.+\..+)$/i', env('HTTP_HOST'), $matches);
define('SUBDOMAIN',empty($matches[1])?false:$matches[1]);
define('HOST',$matches[2]);
define('BASE_URL','http://'.HOST);

if(SUBDOMAIN) $_GET['url'] = 'users/view/'.SUBDOMAIN.(isset($_GET['url'])?'/'.$_GET['url']:'');

It works with or without www. in front of the URL. It also snags the HOST (without subdomain) because you're probably going to want to use it around the site to remove the subdomain from your links when you don't need it.

Posted Dec 18, 2008 by Mark