Wildcard subdomain .htaccess and Codeigniter

2019-04-01 19:53发布

问题:

I am trying to create the proper .htaccess that would allow me to map as such:

http://domain.com/                --> http://domain.com/home 
http://domain.com/whatever        --> http://domain.com/home/whatever
http://user.domain.com/           --> http://domain.com/user 
http://user.domain.com/whatever   --> http://domain.com/user/whatever/

Here, someone would type in the above URLs, however internally, it would be redirecting as if it were the URL on the right.

Also the subdomain would be dynamic (that is, http://user.domain.com isn't an actual subdomain but would be a .htaccess rewrite)

Also /home is my default controller so no subdomain would internally force it to /home controller and any paths following it (as shown in #2 example above) would be the (catch-all) function within that controller.

Like wise if a subdomain is passed it would get passed as a (catch-all) controller along with any (catch-all) functions for it (as shown in #4 example above)

Hopefully I'm not asking much here but I can't seem to figure out the proper .htaccess or routing rules (in Codeigniter) for this.

httpd.conf and hosts are setup just fine.

EDIT #1

Here's my .htaccess that is coming close but is messing up at some point:

RewriteEngine On

RewriteBase /
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

RewriteCond %{HTTP_HOST} ^([a-z0-9-]+).domain [NC]
RewriteRule (.*) index.php/%1/$1 [QSA]

RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [L,QSA]

With the above, when I visit: http://test.domain/abc/123 this is what I notice in $_SERVER var (I've removed some of the fields):

Array
(
    [REDIRECT_STATUS] => 200
    [SERVER_NAME] => test.domain
    [REDIRECT_URL] => /abc/123
    [QUERY_STRING] => 
    [REQUEST_URI] => /abc/123
    [SCRIPT_NAME] => /index.php
    [PATH_INFO] => /test/abc/123
    [PATH_TRANSLATED] => redirect:\index.php\test\test\abc\123\abc\123
    [PHP_SELF] => /index.php/test/abc/123
)

You can see the PATH_TRANSLATED is not properly being formed and I think that may be screwing things up?

回答1:

Ok, I believe I have solved it. Here's what I have so far.

First the .htaccess

RewriteEngine On

RewriteBase /

# if REQUEST_URI contains the word "user" and the
# SERVER_NAME doesn't contain a "." re-direct to the root
# The reason this is done is because of how the last two rules
# below are triggered
RewriteCond %{REQUEST_URI} (user) [NC]
RewriteCond %{SERVER_NAME} !\.
RewriteRule (.*) / [L,R=301]

# Allow files and directories to pass
RewriteCond %{SCRIPT_FILENAME} !-d
RewriteCond %{SCRIPT_FILENAME} !-f

# Codeigniter rule for stripping index.php
RewriteCond $1 !^(index\.php|images|robots\.txt)
RewriteRule ^(.*)$ /index.php/$1 [C]

# Force wild-card subdomains to redirect.
# E.g. http://me.domain/foo/bar/123 as http://domain/user/me/index.php/foo/bar/123/bar/123/
RewriteCond %{HTTP_HOST} ^([a-z0-9-]+).domain [NC]
RewriteRule (.*) /index.php/user/%1/$1/ [L]

And finally routes.php

<?php
// Force routing to userhome controller if URL contains the word "user"
// otherwise force everything else to home controller
$route['user/:any'] = "userhome";
$route[':any'] = "home";
?>

As you can see from above everything works. The only thing I can't figure out is why the last arguments are repeated when I use a subdomain?

If I do: http://domain/foo/bar/123

Then my PATH_INFO is shown as /foo/bar/123/ which is perfect

But if I do: http://me.domain/foo/bar/123

Then my PATH_INFO is shown as /user/me/index.php/foo/bar/123/bar/123/ Which for the most part is OK but why is the parameters repeating in the end?

So yea overall I think it's working. Only thing I'll have to do is have several routes for any controllers I add to my \controllers. Unless there's a way around it?



回答2:

This should work. Please test and let me know if it works:

RewriteEngine On
RewriteCond   %{HTTP_HOST}              ^[^.]+\.domain\.com$
RewriteRule   ^(.+)                     %{HTTP_HOST}$1        [C]
RewriteRule   ^([^.]+)\.domain\.com(.*) /$1$2                 [L]
RewriteRule   ^(.*)                     /home$1               [L]