2011-10-04 81 views
2

我想使用mod_rewrite將一些人性化的URL改寫成名爲php(它位於web根目錄中,因爲mod_rewrite顯然不會讓您重寫爲web根目錄之外的文件)中的任意文件。如何防止mod_rewrite多次重寫URL?

/  --> /php/home.php 
/about --> /php/about_page.php 
/contact --> /php/contact.php 

這裏是我的重寫規則:

Options +FollowSymlinks 
RewriteEngine On 

RewriteRule ^$ php/home.php [L] 
RewriteRule ^about$ php/about_page.php [L] 
RewriteRule ^contact$ php/contact.php [L] 

不過,我也希望阻止用戶從這個php目錄直接訪問文件。如果用戶輸入任何 URL以/php開頭,我希望他們得到一個404頁面。

我嘗試添加在最後這個額外的規則:

RewriteRule ^php php/404.php [L] 

...(其中404.php是輸出404頭和一個「未找到」消息的文件)

但當我訪問/或​​或/ contact時,我總是被重定向到404。看來最終的RewriteRule甚至適用於內部重寫的URL(因爲它們現在都以/php開頭)。

我認爲[L]標誌(在前三個RewriteRules上)應該阻止應用更多規則?難道我做錯了什麼? (或者是有一個更聰明的方式做我想要做什麼?)

回答

0

[L]標誌應該只在最後一個規則,

L - 最後一條規則 - 在這裏停止重寫的過程和請不要應用任何更多的重寫規則&,因爲您面臨的問題。

+0

但是,這正是我想要的,在這裏結束重寫過程。我說我*不希望它在匹配後繼續應用後續規則。但是最終規則總是被執行,即使之前的規則(帶有[L]標誌)已經被執行。爲什麼? – callum

0

我有類似的問題。我有一個用PHP編寫的基於模型 - 視圖 - 控制範例的內容管理系統。最基本的部分是mod_rewrite。我已成功阻止全球訪問PHP文件。技巧名稱爲THE_REQUEST

什麼問題?

重寫模塊重寫URI。如果URI與規則相匹配,則會重寫該規則,並將其他規則應用於新的重寫URI。但!如果匹配的規則以[L]結尾,引擎實際上並未終止,但會再次啓動。然後新的URI不會匹配以[L]結尾的規則,繼續並匹配最後一個。結果?程序員在出乎意料的404錯誤頁面上發出不良言語。然而,電腦的確如此,你說什麼也不說,你想要什麼。我在我的.htaccess文件中有這個:

RewriteEngine On 
RewriteBase/
RewriteRule ^plugins/.* pluginLoader.php [L] 

RewriteCond %{REQUEST_URI} \.php$ 
RewriteRule .* index.php [L] 

這是錯誤的。即使以plugins/開頭的URI也被重寫爲index.php

解決方案

需要當且僅當原來的應用規則 - 沒有被改寫 - URI的規則相匹配。遺憾的是,mod_rewrite沒有提供任何包含原始URI的變量,但它提供了一些THE_REQUEST變量,其中包含HTTP請求頭的第一行。這個變量是不變的。重寫引擎工作時不會改變。

... 
RewriteCond %{THE_REQUEST} \s.*\.php\s 
RewriteRule \.php$ index.php [L] 

正則表達式是不同的。它不僅適用於URI,而且適用於標題的整個第一行,這意味着類似於GET /script.php HTTP/1.1。但是關鍵的規則是這一次只有在用戶明確直接請求一些PHP腳本時才應用。重寫的URI不被使用。