6

I'm trying to make any or a set of subdomains redirect to a folder inside "controllers" folder of a CI installation. I've tried a bunch of stuff found here on SO but none work for my project or have the same specs I need. Since I am a bit of a noob when it comes to .htaccess so I've figured I might just ask someone more qualified in here. Here are the specs:

  • using this awesome .htaccess file as a base
  • need to redirect at least this three subdomains (www|admin|api) to /application/controllers/(www|admin|api) equivalent folders
  • without loosing the REQUEST_URI (just saying)
  • and without actually changing the URL in the address bar

Example: http://api.domain.com/some/uri/segments should internally redirect to CI_installation_folder/application/controllers/api/some/uri/segments

I've tried something like this (and variations):

RewriteCond %{HTTP_HOST} ^(www|admin|api) [NC] RewriteRule ^(.*)$ /%1/$1 [L,R=301] 

or replaced the RewriteRule with 2 other lines like so:

RewriteCond %{ENV:REDIRECTED} !true RewriteRule ^(.*)$ [L,R=301,E=REDIRECTED:true] 

to prevent the loop, but all I can get is either a looping redirect (1st case) or even a 500 server error on some variations :(

Adding this

RewriteCond %{REQUEST_URI} !^/(www|admin|api) [NC] 

will also not work since I'm not changing the URL in the address bar. I also haven't got any success with the [P] flag also.

Can anyone help? Thanks!

3 Answers 3

4

Did you try using the route configuration of Codeigniter?

you don't have to use htaccess rewrite - although its a valid approach, you can just check for the subdomain in the config/route.php file and set the routing for your subdomains.

switch ($_SERVER['HTTP_HOST']) { case 'admin.domain.com': $route['(:any)'] = "admin/$1"; // this will set any uri and add the controler fodler to it $route['default_controller'] = "admin/home"; // set the default controller for this subdomain break; case 'api.domain.com': $route['(:any)'] = "api/$1"; // this will set any uri and add the controler fodler to it $route['default_controller'] = "api/home"; // set the default controller for this subdomain break; } 

If you would like it to be a more generic/ dynamic routing, you can have it like this (in the same config/route.php file):

$controllerFolderName = array_shift((explode(".",$_SERVER['HTTP_HOST']))); $route['(:any)'] = $controllerFolderName."/$1"; $route['default_controller'] = $controllerFolderName."/home"; 

this routing will work for all subdomains and will set the default routing to a folder inside the controller folder with the same name as the subdomain, so for a domain like api.domain.com you will have the route set to api etc.

it is important that you keep the same logic for all folder name that they will always match your subdomain and i would also suggest to add an error handling system for visitors with no subdomain (http://domain.com) and for cases where you have the subdomain but a folder with that name does not exists (you can do that with file_exits)

Sign up to request clarification or add additional context in comments.

3 Comments

Thank you for the quick response but my idea was to do it at the lowest possible level. And if you also take into consideration that I'm not your average "just make it work" guy you'll realize this is not a valid solution for me :|. I want something dynamic and easy to maintain without having to duplicate rules and routes and stuff.
So, you want life to be easy.... that is a very good approach... let me update my response
This approach is a bit cleaner :) And I might just be a bit too picky but when I said I wanted to do this at the lowest level possible I was actually expressing my desire for this problem to be solved using a .htaccess redirect because performance matters in my case :)
1

After a few more hours of digging I think I solved the problem. Here's how (for the ones that care):

# Subdomains to Folders + Enforce www RewriteCond %{HTTP_HOST} ^(www|admin|api) [NC] RewriteRule ^(.*)$ http://www.localhost/%1/$1 [L,P,S=1] RewriteRule ^(.*)$ http://www.localhost/$1 [L,R=301]

I combined the internal redirect with the www enforcer rule. All there is to do after this is configure the Apache Server to accept and properly redirect the PROXY request :)

Have phun!

Comments

0

Tried the suggestions above but ran into a lot of issues. Found a solution that allows you to route all URIs to a directory based on the subdomain, while allowing you to use the codeigniter routing functionality as it was intended.

First, place the follwing code in your application/core folder:

class MY_Router extends CI_Router { public function __construct($routing=NULL) { $routing['directory'] = explode('.',$_SERVER['HTTP_HOST'])[0]; parent::__construct($routing); } } 

Codeigniter will now place you subdomain directory before all controllers when routing. (i.e. ...application/subdomain_dir/class/method)

Next, set your base_url in the config.php file.

$subdomain = explode('.',$_SERVER['HTTP_HOST'])[0]; $config['base_url'] = 'http://'.$subdomain.'.domain.com'; 

Finally, use the routes.php as it was intended.

$route['default_controller'] = "home"; 

The default controller above will now be routed to subdomain_dir/home. Similarly, if you navigate to subdomain.domain.com/class/method, you will be routed to subdomain_dir/class/method.

Hope this helps someone in the future.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.