2011-06-14 75 views
7

我有以下網址...怎樣才能mod_rewrite的匹配規則只有一次

http://localhost/http.mygarble.com/foundationsofwebprogramming/86

...我想轉換成以下:

http://localhost/http.mygarble.com/php/blog.php?subdomain=foundationsofwebprogramming&page=posts&label=86

我想我可以用下面的規則做到這一點:

RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L] 

但是我發現這個規則被反覆應用,導致內部服務器錯誤。我明白,當使用此規則轉換URI時,生成的URI也將匹配規則,因此它將再次應用ad-infinitum。

我以前的(當然是非常模糊的)理解是,[L]標誌會停止進一步的處理,但我現在明白,這只是意味着只有其餘規則被跳過,並且不會停止重寫引擎的運行再次通過規則。

我可以通過添加以下條件解決這個問題...

RewriteCond $0 !php/blog.php 
RewriteRule ([^/]+)/([^/]+)$ php/blog.php?subdomain=$1&page=post&label=$2 [NC,L] 

...或者寫一個更具體的正則表達式。但是我真正想要做的是找到一種方法,一旦這個規則匹配一次,就停止嘗試任何進一步匹配的重寫引擎。這可能嗎?

非常感謝。

回答

16

通常使用2種方法。

第一個是Rewrite Condition測試,請求的文件不是真實文件。當內部遞歸出現時,你的php/blog.php是一個真正的文件,並且第二次執行rewriterule。副作用是,它存在不會被改寫爲文件的任何請求(可以是很好的副作用)

RewriteCond %{REQUEST_FILENAME} !-f 

第二個解決方案是檢查與內部重定向不是:

RewriteCond %{ENV:REDIRECT_STATUS} ^$ 

這個第二個解決方案的副作用是,如果之前應用了其他某些規則(如果您希望在第一次重寫實際執行後運行一些內部重定向),則不能應用rewriteRule。

編輯

完成,我將增加第三法:[NS]或[nosubreq]標籤似乎是在做同樣的事情。內部重定向後防止規則使用。

+0

第二個解決方案是理想的。我想要的唯一重定向是外部的,所有規則都只能運行一次。謝謝。 – 2011-06-14 14:14:46

+0

不幸的是,我沒有聲望投票答覆你的答案,也許有人會代表我做。再次感謝。 – 2011-06-14 14:15:51

+0

@詹姆斯史密斯:你不需要提高我的答案,你應該「接受」它(這樣我就得到了綠色標記)。 – regilero 2011-06-14 14:28:58

4

第三種方法是將apache升級到2.3.9或更高版本,並使用[END]標誌而不是[L]。

沒有副作用

相關問題