2008-09-22 43 views
11

我正在建立一個相當大的網站,我的.htaccess開始感到有點臃腫,有沒有一種方法來取代我目前的系統 - 每一個可能性的一個規則可以傳遞的變數的數量,一個可以捕捉到所有可以考慮不同數量輸入的表達?apache mod_rewrite任何數量的可能性的一個規則

例如我目前有:

RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4&$5=$6 
RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4 
RewriteRule ^([a-z]+)/([^/]*)$ /index.php?mode=$1&id=$2 
RewriteRule ^([a-z]+)$ /index.php?mode=$1 

第一反向引用總是模式和(如果有的話更多存在)第二總是ID,之後的名稱之間的任何進一步向引用備用輸入和它的值

http://www.example.com/search 
http://www.example.com/search/3039/sort_by/name_asc/page/23 

我希望能夠有一個表達式來優雅地處理所有的輸入。

+0

這不是臃腫:)你應該看到我的一些Apache配置。嚴重的是,4條重寫規則是完全合理的。 – Aeon 2008-09-22 23:35:11

+0

這只是我的配置的一部分,我覺得我可以改善,但不知道如何,還有其他部分,我目前正在工作;) – JimmyJ 2008-09-23 10:10:29

回答

8

不喜歡的Drupal:

RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule ^(.*)$ index.php?q=$1 [L,QSA] 

,然後使用PHP代碼這樣的事情

$pathmap =(); 
if ($_GET["q"]){ 
    $path = split("/", $_GET["q"]); 
    for ($i=0; $i+1<count($path); $i++){ 
     $pathmap[$path[$i]] = $path[$i+1]; 
     $i++; 
    } 
} 
+0

不完全是我正在尋找,但一個很好的替代仍然 – JimmyJ 2008-11-02 18:13:16

+0

如何做你稍後在腳本中處理這個問題? – 2009-04-04 18:35:36

2

我不相信他們是一個方式來處理所有的東西在你的腳本 - 但我假設你最好的選擇是讓腳本「index.php」處理一條路徑,而不是必須做很多後備引用。

因此,例如,你的重寫規則將

RewriteBase/
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule . /index.php [L] 

或者類似的......這將進而使$ _ SERVER [「REQUEST_URI」]變量包含路徑信息,您可以拆分和解析。

$path = split('/', $_SERVER['REQUEST_URI']); 
array_shift($path); // We always have a first null value 
$mode = array_shift($path); 

這結束了包含模式$模式,以及包含你的路徑的其餘部分元素的數組$路徑,所以

http://example.com/foo/bar/baz 

會離開你$模式是「富'和$ path是包含'bar'和'baz'的數組

7

我不知道它是否可以用單個表達式完成,但是可以使用固定數量的表達式完成,無論多長時間查詢字符串。

你的mod_rewrite規則將被重複調用,給你什麼有時稱爲mod_rewrite遞歸。有技術可以避免它,但我認爲你想使用它。

成立,取代了過去的對與名稱的規則=值&

保持套結對輸入查詢字符串輸出。每次通過時,您的查詢字符串將變得更長,並且您的URL會變短。

最終你只有一個匹配你最後一條規則的值。

你必須捕捉查詢字符串

RewriteCond %{QUERY_STRING} ^(.*)$ 

然後您%1

它添加到輸出你最終四行。

我知道四條線是你開始的,但是你可以根據需要匹配儘可能多的參數,而無需添加第五條線。

RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L] 
RewriteCond %{QUERY_STRING} ^(.*)$ 
RewriteRule ^([^/]+)/ $1.php?%1 [L] 

這將改寫以下

/mypage/param1/val1/param2/val2/param3/val3/...  ---> 
/mypage.php?param1=val1&param2=val2&param3=val3&... 

當只有一個剩餘參數停止。它將採用第一個「參數」並用該名稱調用.php文件。 param/val對的數量沒有限制。