Subdomains leading to Codeigniter Controllers?
Asked Answered
P

4

24

This seems like a common request, but I haven't been able to find definitive instructions on doing something like this.

I'd like a subdomain to trigger a certain controller on my CI installation. For example:

students.mysite.com : would open mysite.com/students (technically: mysite.com/index.php/students. controller: students)

teachers.mysite.com : would open mysite.com/teachers

While preserving the subdomain when traversing deeper. For example:

students.mysite.com/help : would open mysite.com/students/help (controller: students(), method: help())

students.mysite.com/help/contact : would open mysite.com/students/help/contact (controller: students(), method: help(), argument: "contact")

students.mysite.com/help/contact/email : would open mysite.com/students/help/contact (controller: students(), method: help(), arguments: "contact", "email")

I realize that something.mysite.com right now returns an error. So I figure:

Step 1 would be allowing anything.mysite.com to return the root (mysite.com/index.php)

Step 2 would be reading the subdomain and calling that controller

Step 3 would be reading the first argument after the first "/" and calling that method of the controller, and passing the remaining url parts as arguments

I guess really I'm stumped at Step 1. I'm on a shared hosting account, is this something I can do via CPanel? I tried adding a subdomain for *.mysite.com without any luck (unless I just needed to wait longer for propogation, but I feel the chances are higher that I got it wrong).

Back on my home WAMP installation, I'd change up httpd.conf, right? Can I acheive this effect without modifying that file (since I probably can't, since I'm shared using webhostinghub.com)

Phew, thanks for your time! - Keith

Pelligrini answered 22/10, 2013 at 8:51 Comment(9)
Have you set up a wildcard dns for your domain? The Apache config is the other half of it. You need a CNAME or A record pointing all *.domain.com to your website. Google would help you here.Frogfish
Thanks for the tip. I just set up a *.mysite.com CNAME record with a value of mysite.com. That will take care of step 1 right? It doesn't seem to be working yet, so I'm going to let it propogate then try again laterPelligrini
can't give you code off the top of my head, but your .htaccess should be able to rewrite the subdomains the way you like, I would thinkNabonidus
Did you solve this? Your question is now the top result in Google for this particular topic.Borsch
Nope, not yet. I kind of gave up and we're hosting different sites on different servers. I'm leaving it open hoping someone'll know how to do thisPelligrini
@Prodikl Does your hosting support wildcard subdomains? That is the first step, not all shared hostings support redirecting *.something.com to another IP address.Checker
Well, I can set up sub-domains, but I'm not sure about wildcard subdomains, I'll have to look into it!Pelligrini
@Prodikl You have to check that first... I already implemented a mapping between CodeIgniter and subdomains... so I know it works, but you have to make sure that your registrar (which may not be the same as your hosting provider) allows you to add a wildcard C Name (*.domain.com) so that anything that is under the .domain.com goes to a specific IP, then with apache you'll redirect everything to CI, finally in CI you'll catch the request subdomain.Checker
May be help you #19664349Abbott
D
36

As you want to use a particular domain to lead to your controllers, what I came up with was using the application/config/routes.php file to achieve it. The idea is load different controllers depending on what subdomain you use, so, instead of writing a list of routes for your domain, you write a list of routes DEPENDING on the domain you're accessing from:

switch ( $_SERVER['HTTP_HOST'] ) {
    case 'students.mysite.com':
        $route['default_controller'] = "students";
    break;
    case 'teachers.mysite.com':
        $route['default_controller'] = "teachers";
    default:
        // The list of your $routes lines at is was...
    break;
}

To make this work, you only have to point the subdomain to your CI project (Dwayne Towell in the step 1 of the other answer explains how to do it perfectly) and you'll have everything working, your shared hosting won't be a problem and you won't have to configure the server.

UPDATE

After reading this answer, check the answer from @Josh (https://mcmap.net/q/546825/-subdomains-leading-to-codeigniter-controllers) as it offers a wonderful way to organize the routing code to avoid unexpected routing behaviour with the controllers. It's worthy reading it (and upvoting it, ;D)

Decidua answered 26/2, 2014 at 19:14 Comment(5)
Damn, very smart solution to the problem. Thanks a lot!Pelligrini
No-touching a .htaccess file, and controllers exclusivity for subdomains, great answer.Pinckney
But you'll have issues between different ENVIRONMENTs... I am working on a perfect solution as this does not solve mine.Perform
@Ema4rl, at the end this is about routing. If you have several environments, the only thing that may happen is that you'll need something different that a switch (maybe an in_array('dev.student.site.com', 'student.site.com') or even two switch` and select which one you want to use depending on the environment. Or even better, create a Router class where you pass the domain and the environment and it returns automatically the controller.Decidua
Also from your hosting you should redirect from subdomain to public_html.Novobiocin
J
4

Step 1: In CPanel, in Domains, in subdomains, add *.mysite.com (you only enter the * part) to redirect to /public_html/ (you enter nothing and/or delete wildcard) (or set this to whatever the current default value for www.mysite.com is currently.

Step 2 & 3: Use mod_rewrite to capture subdomain and move it to the "directory" part of the URL. I suspect it will be something like: (but I haven't tried it yet, RewriteLogLevel 9 is your friend)

RewriteEngine on
RewriteCond %{HTTP_HOST} ^([^\.]+)\.mysite\.com$ [NC]
RewriteRule ^(.*)$ http://www.domain.com/index.php/%1/$1 [L]

I also don't know if you can do the above using .htaccess. I have only done rewriting from httpd.conf.

Jeromejeromy answered 24/2, 2014 at 7:34 Comment(2)
Thanks a lot for this write up. I tried something very similar but it didn't work last time. I'll try writing it the way you did and post back with results!Pelligrini
How do I modify this .htaccess snippet to allow www. prefix?Horary
U
4

In application/config/routes.php file, you need to write

$subDomains = array();
$subDomains['students.mysite.com'] = "student";
$subDomains['teachers.mysite.com'] = "teachers";

if(array_key_exists($_SERVER['HTTP_HOST'], $subDomains)) {
  $route['default_controller'] = $subDomains[$_SERVER['HTTP_HOST']];
}
Ulrikeulster answered 11/7, 2015 at 12:47 Comment(0)
I
3

!!!
A very important step you don't want to forget in addition to Chococroc's great example is to route any segments back to the subdomain controller otherwise you will end up routing to a controller that probably doesn't exist. Example using Chococroc's existing code

switch ( $_SERVER['HTTP_HOST'] ) {
    case 'students.mysite.com':
        $route['default_controller'] = "students";
    break;
    case 'teachers.mysite.com':
        $route['default_controller'] = "teachers";
    default:
        // The list of your $routes lines at is was...
    break;
}

Navigating to 'teachers.mysite.com/login' will load the 'login' controller NOT the expected 'teachers' controller.

If you don't want this unexpected behavior you need to route any segments back to the subdomain controller. They will now be a function of that controller.

switch ( $_SERVER['HTTP_HOST'] ) {
    case 'students.mysite.com':
        $route['default_controller'] = "students";
        $route['(:any)'] = "students/$1";
    break;
    case 'teachers.mysite.com':
        $route['default_controller'] = "teachers";
        $route['(:any)'] = "teachers/$1";
    default:
        // The list of your $routes lines at is was...
    break;
}

Navigating to 'teachers.mysite.com/login' will now load the 'teachers' controller and run the 'login' function within that controller.

There are other things you could enforce such as a subfolder for each domain, etc.

Indeterminism answered 18/11, 2017 at 17:25 Comment(1)
Very nice addition! I've added an update in my answer to help people finding yours, it offers very good advice, :DDecidua

© 2022 - 2024 — McMap. All rights reserved.