2012-10-12 20 views
8

我的頁面沒有進行重定向,因爲它應該是由於我的.htaccess文件作爲設定:mod_rewrite的例外特定文件

RewriteEngine on 
RewriteCond $1 !^(index\.php|resources|robots\.txt) 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ index.php/$1 [L,QSA] 

我使用此設置爲我的MVC框架,所以我得到的URL像然而/controller/method/argument當我重定向到/forum/login.php時,它會切換到/ forum /。

我怎樣才能將其添加爲例外,這樣我就可以重定向到/forum/login.php

我發現了另外的.htaccess我/論壇/目錄可能這會造成問題呢?

# BEGIN PunBB 

<IfModule mod_rewrite.c> 
    # MultiViews interfers with proper rewriting 
    Options -MultiViews 

    RewriteEngine On 

    # Uncomment and properly set the RewriteBase if the rewrite rules are not working properly 
    #RewriteBase/

    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule . rewrite.php [L] 
</IfModule> 

回答

21

首先,我會告訴你如何看你重寫規則:

您開始第(或下)重寫規則條目:

RewriteRule ^(.*)$ index.php/$1 [L,QSA]

第一個參數是一個正則表達式可以匹配你的請求的URL。 ^(.*)$匹配的一切,並將這一點,可以在以後使用的變量裏面的「一切」。

僅當有前述的RewriteCond條目,它們接下來評價:

RewriteCond $1 !^(index\.php|resources|robots\.txt)

$1是重寫規則的第一括號內相匹配的內容的引用。這是相比於第二參數,這是一個正則表達式,說明幾個明確的名稱,和!否定表達,例如只有當正則表達式不匹配時,此規則才允許執行RewriteRule。如果此條件返回true,則會查看下一個條件。

RewriteCond %{REQUEST_FILENAME} !-f

如果請求的文件名是在硬盤沒有真正的文件,這種情況是真實的。

RewriteCond %{REQUEST_FILENAME} !-d

如果請求的文件名是沒有真正的目錄,這種情況是真實的。

只有當所有這些條件都爲真(它們與鏈接起來),我們回過頭來重寫規則:

RewriteRule ^(.*)$ index.php/$1 [L,QSA]

此改寫步驟的結果被定義爲第二和第三參數。 $1再次被用作與所述匹配的內容,並且所述參數定義該規則,如果最初匹配,將是最後一個規則(L),並且在重寫目標定義的任何查詢字符串將被附加到任何查詢字符串在原始網址(QSA)中。

批判:

通常重寫MVC框架試圖儘可能高性能。您的重寫條件都必須經過評估才能成功重寫。只有當任何RewriteCond返回false時,該停止纔會停止。每一個被重寫的請求都會受到大量的cpu密集測試的影響。首先是RewriteRule正則表達式,然後是第一個RewriteCond中的正則表達式,然後是文件系統上的兩個硬盤測試用於文件存在。

另一方面,第一個RewriteCond似乎是不必要的。它測試某些名稱,如果找到,則會中止重寫。 「index.php」應該由第二個RewriteCond檢測,因爲它是一個現有的文件(如果不是,重寫工作如何)。任何以「資源」開頭的內容都將被匹配,但可能不應該出於同樣的原因:現有資源將由第二個RewriteCond找到。最後是「robots.txt」文件。如果你想在機器人抓取你的網站時避免404,那麼有一個好主意,可能是emtpy。

由於您沒有更改查詢字符串中的任何內容,因此不需要[QSA]指令。

改進:

RewriteEngine on 
RewriteCond %{REQUEST_FILENAME} -f [OR] 
RewriteCond %{REQUEST_FILENAME} -d 
RewriteRule ^.*$ - [L] 
RewriteRule ^.*$ index.php [L] 

第一重寫規則將匹配整個請求的路徑。兩個RewriteCond與[OR]連接,所以返回true的第一個RewriteCond將取消進一步評估。第一個RewriteCond測試是否存在請求的文件。如果存在,則返回true,處理返回到第一個RewriteRule。目標表達式是「 - 」,意思是「不要重寫」。 [L]停止對重寫規則的進一步處理。所以最後,對於現有文件,我們只有一個正則表達式和一個文件系統測試,並且之後,這個現有文件將被髮送到瀏覽器。

如果找不到文件,第一個RewriteRule和RewriteCond不會被觸發,所以[L]不會停止進程。所以第二個RewriteRule被執行。這是一個無條件的,正則表達式和以前一樣,匹配所有內容,並將其重寫爲「index.php」。

如果有任何文件存在,包括/forum/login.php,此重寫將不會調用您的index.php。

您可以更改第二個RewriteRule ^.*$ index.php/$0 [L]如果你想繼續分析$_SERVER['PATH_INFO']代替$_SERVER['REQUEST_URI']

+0

謝謝!幾個月來我一直在尋找這個級別的解釋。 – wallyk

+0

現在糾正它的工作。 –

+2

這是如此令人難以置信的徹底,需要更多的信貸比它給出。 –

2

嘗試這樣的:

RewriteEngine on 
RewriteCond $1 !^(index\.php|forum|resources|robots\.txt) 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule ^(.*)$ index.php/$1 [L,QSA] 

這:

# BEGIN PunBB 

# ---------------------------------------------------------------------- 
# Start rewrite engine 
# ---------------------------------------------------------------------- 

<IfModule mod_rewrite.c> 
    # MultiViews interfers with proper rewriting 
    Options -MultiViews 

    RewriteEngine On 

    # Uncomment and properly set the RewriteBase if the rewrite rules are not working properly 
    RewriteBase /forum/ 

    RewriteCond %{REQUEST_FILENAME} !-f 
    RewriteCond %{REQUEST_FILENAME} !-d 
    RewriteRule . rewrite.php [L] 
</IfModule> 


# ---------------------------------------------------------------------- 
# Better website experience for IE users 
# ---------------------------------------------------------------------- 

# Force the latest IE version, in various cases when it may fall back to IE7 mode 
# github.com/rails/rails/commit/123eb25#commitcomment-118920 
# Use ChromeFrame if it's installed for a better experience for the poor IE folk 

<IfModule mod_setenvif.c> 
    <IfModule mod_headers.c> 
     BrowserMatch MSIE ie 
     Header set X-UA-Compatible "IE=Edge,chrome=1" env=ie 
    </IfModule> 
</IfModule> 

<IfModule mod_headers.c> 
    # Because X-UA-Compatible isn't sent to non-IE (to save header bytes), 
    # We need to inform proxies that content changes based on UA 
    Header append Vary User-Agent 
    # Cache control is set only if mod_headers is enabled, so that's unncessary to declare 
</IfModule> 


# ---------------------------------------------------------------------- 
# UTF-8 encoding 
# ---------------------------------------------------------------------- 

# Use UTF-8 encoding for anything served text/plain or text/html 
AddDefaultCharset utf-8 

# Force UTF-8 for a number of file formats 
AddCharset utf-8 .html .css .js .xml .json .rss 


# ---------------------------------------------------------------------- 
# A little more security 
# ---------------------------------------------------------------------- 

# Do we want to advertise the exact version number of Apache we're running? 
# Probably not. 
## This can only be enabled if used in httpd.conf - It will not work in .htaccess 
# ServerTokens Prod 


# "-Indexes" will have Apache block users from browsing folders without a default document 
# Usually you should leave this activated, because you shouldn't allow everybody to surf through 
# every folder on your server (which includes rather private places like CMS system folders). 
<IfModule mod_autoindex.c> 
    Options -Indexes 
</IfModule> 

# END PunBB 
+0

不,它仍然切割到/論壇/。 –

+0

我編輯了我的代碼片段。現在試試。 – 2012-10-12 19:36:38

+0

還沒有被切斷,我檢查了我的Web服務器中的所有.htaccess文件。 –