apache rewrite and VirtualDocumentRoot

參考資源:http://phorum.study-area.org/index.php?topic=17120.0

設定讓每個使用者可以自動對應到某個虛擬伺服器的方式


UseCanonicalName On

VirtualDocumentRoot /home/%1/www/%2

例如

http://mlwmlw.blog.mlwmlw.org/ 對應至 /home/mlwmlw/www/blog

ohmygod.test.mlwmlw.org/ 對應至 /home/ohmygod/www/test

%1 %2 %3 則是按照 dns 名稱的順序對照到實體目錄上

.htaccess rewrite

透過 rewrite 設定將某個網址導到某個資料夾下的 index.php  ,常用於 codeIgniter 的設定,

官方教學的方式如下,感覺只能處理網址是虛擬伺服器的情況,

例如上述的 blog.mlwmlw.org/index.php,才能成功,


RewriteEngine On
RewriteCond %{REQUEST_URI} !^(/index\.php|/img|/js|/css|/robots\.txt|/favicon\.ico)
RewriteRule ^(.*)$ /index.php/$1 [L]

否則都會導頁到根目錄下,例如我用 http://mlwmlw.org/~user/test/index.php,

他則會幫我弄成 http://mlwmlw.org/index.php =__=。

如果想要將網址http://mlwmlw.org/~user/dir/index.php/xxx/yyy

導至 /home/user/www/dir/index.php/xxx/yyy 下,則可以用以下的 rewrite。

透過 REQUEST_FILENAME 會產生完整的要求目錄的原理,

將他與時紀要求的路徑對應去產生群組 %1 %2 變數來使用接在 RewriteRule 內。

感覺 rewrite 實在有點複雜…甚至還有專書在討論

Definitive-Guide-Apache-mod_rewrite

搞了三四個專案的失敗經驗才成功寫出這個規則…否則以往都要依照使用者設定 virtual host ~

但是最上面的那個設好也是可以不用一一指定啦~

其實有一大堆作法…可以用…博大精深的 httpd configuration…

RewriteEngine on
RewriteCond $1 !^(index.php|images|robots.txt|assets|temp)
RewriteCond %{REQUEST_FILENAME} ^/home/(.+)/www/(.+)/(.*)
RewriteRule ^(.*)$ /~%1/%2/index.php/$1 [L]

RewriteRule 對應的正規在比照的是 mlwmlw.org/index.php?abc=123 網址裡面的 /index.php?abc=123
所以如果寫 RewriteRule a http://a.com 則是 index.php?abc=123 裡面有出現 a 這個字就會轉頁,
如果要完整比對整個字串應該是要加上 ^a$ 來指定從開頭對照到結尾

%{REQUEST_FILENAME} 看到的是完整的要路徑 , 例如 /home/mlwmlw/www/project/index.php
%n 代表的是 RewriteCond 正規裡面符合條件的群組順序,例如上面的

RewriteCond %{REQUEST_FILENAME} ^/home/(.+)/www/(.+)/(.*)

對照到 /home/mlwmlw/www/project/index.php 的 /home/(%1)/www/(%2)/index.php 這樣 %1 , %2 就能在 Rule 裡面又拿來當規則,

$n 代表的是 RewriteRule 前半段的正規符合的群組,例如

http://mlwmlw.org/~mlwmlw/project/hello/world 會提取出 /hello/world 來比較,^(.*)$ 則是把整段都拿來 對應到 $1,

就是把參數都往 /~mlwmlw/project/index.php/$1 <- 這裡丟 變成 /~mlwmlw/project/index.php/hello/world

另外一提這裡比較特別與奇怪的用法是一開始的
RewriteCond $1 !^(index.php|images|robots.txt|assets|temp)
由於這裡根本還沒用到 RewriteRule 所以 $1 指的意思好像比較不明,
好像比較少這樣用,但是一樣是指 /hello/world 這一段,
如果有這段是採用 /index.php or /assets .. 等規則開始的話就直接跳掉了。
另外加上一個更完整的情境…與 RewriteCond and 的用法

RewriteEngine on
RewriteCond $1 !^(index.php|images|robots.txt|assets|temp)
RewriteCond %{HTTP_HOST} ^.+\.site\.com$
RewriteCond %{REQUEST_FILENAME} ^/home/(.+)/www/(.+)/(.*)
RewriteRule ^(.*)$ /%2/index.php/$1 [L]

RewriteCond $1 !^(index.php|images|robots.txt|assets|temp)
rewriteCond %{REQUEST_FILENAME} ^/home/(.+)/www/(.+)/(.*)
rewriteRule ^(.*)$ /~%1/%2/index.php/$1 [L]
  
if [^index.php,^images,^robots.txt,^temp] in url and host reg *.site.com :   
  (%1, %2, %3) = filename reg /home/(*)/www/(*)/(*) 
  $1 = url 
  redirect /%2/index.php/$1 
else if [^index.php,^images,^robots.txt,^temp] in url : 
  (%1, %2, %3) = filename reg /home/(*)/www/(*)/(*) 
  $1 = url   redirect /~%1/%2/index.php/$1

網站在 /home/mlwmlw/www/apple/ 設定好網址,
可以用 http://mlwmlw.site.com/apple 進去
也可以用 http://site.com/~mlwmlw/apple 進去