Subdomaining with Cake

This article is also available in the following languages:
By 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) :
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:

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 : $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

  • Posted 09/28/09 04:59:58 AM
    This article was very helpfull, but I still have a question.

    let's say you have:

    username.domain.com and want to be able to make a page like:

    username.domain.com/friends
    username.domain.com/blog

    How would this be done ? Does the router needs an extra line for this or can it be done in the user_controller.php using an extra view per function ?
  • Posted 09/18/09 05:31:27 AM
    Very helpful article. I have used .htaccess for subdomaining purspose but the code in bootstrap.php is efficient and more comprehensive approach for cakephp.

    Thanks
  • Posted 12/18/08 04:18:00 AM
    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 11/24/08 04:47:40 PM
    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 11/24/08 03:57:46 AM
    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 08/28/08 05:14:38 PM
    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 03/20/08 04:11:49 PM
    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 02/29/08 01:27:23 AM
    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 02/19/08 06:09:55 PM
    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 02/05/08 04:25:38 AM
    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 02/05/08 10:39:37 AM
      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.

Comments are closed for articles over a year old