首先,我會告訴你如何看你重寫規則:
您開始第(或下)重寫規則條目:
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']
。
謝謝!幾個月來我一直在尋找這個級別的解釋。 – wallyk
現在糾正它的工作。 –
這是如此令人難以置信的徹底,需要更多的信貸比它給出。 –