Subdomains leading to Codeigniter Controllers?

2019-01-31 09:10发布

问题:

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

回答1:

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.



回答2:

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.



回答3:

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']];
}


回答4:

!!!
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.