2014-10-27 47 views
1

我使用PHP編寫了一個小型CMS,並且需要將所有請求重定向到該文件(在我的情況下稱爲cms.php)。例如用url作爲參數將每個請求重寫爲一個文件作爲參數

/~ps0ke/ -> /~ps0ke/cms.php?path=index.html 
/~ps0ke/projects/cms.html -> /~ps0ke/cms.php?path=projects/cms.html 

等等。還有一個lang參數,如果en/位於該目錄之前,則該參數被設置。這不應該很重要,因爲我在添加多語言支持之前存在問題。現在,我使用Apache及以下.htaccess實現重寫:

RewriteEngine On 
RewriteBase /~ps0ke/ 

# Serve index.html via cms.php when base dir or index.html is requested. Also 
# set the language. 
RewriteRule ^((en)/)?(index.html)?$ cms.php?lang=$2&path=index.html [NC,L] 

# Serve everything else via cms.php. Also set the language. 
# Serving from the page subdirectory is due to a problem with all-wildcard 
# RewriteRule. This might be fixed. 
RewriteRule ^((en)/)?page/(.*)$ cms.php?lang=$2&path=$3 [NC,L,B] 

您可能會注意到,有在RewriteBase以及實際軌跡之間的附加page/。我這樣做是因爲僅僅匹配

RewriteRule ^((en)/)?(.*)$ cms.php?lang=$2path=$3 [NC,L,B] 

根本行不通。我不明白爲什麼。當我在

Array 
(
    [lang] => 
    [path] => cms.php 
) 

使用規則如上輸出$_GET的結果,無論實際GET路徑中,path GET變量總是被設置爲腳本的名稱。我只是不明白爲什麼。

我不想擁有page/前綴的原因是它保持向後兼容性。 CMS專門爲文件系統提供正常的文件結構並建立其導航等。因此,在GET路徑中顯示實際的真實文件結構會很好。因此,即使有人再次移除CMS,鏈接仍然有效。

只是更容易參考,我把所用的選項Apache手冊條目:

NC | NOCASE

的[NC]標誌的使用造成的重寫規則在 要匹配不區分大小寫的方式。也就是說,它不關心字母 是否在匹配的URI中顯示爲大寫或小寫。

B(逸出反向引用)

的[B]標誌指示重寫規則應用轉換之前轉義非字母數字 字符。

大號|最後

的[L]標誌使mod_rewrite的停止處理規則集。在大多數情況下,這意味着如果規則匹配,則不會處理其他規則 。這對應於Perl中的最後一個命令,或對應於C中的break命令。使用此標誌來指示當前應使用 規則而不考慮其他規則。

讚賞任何幫助(修復或解釋)!提前致謝!

回答

1

由於您的規則執行兩次,您正在進入此問題。您可以通過避免所有資源(js,image,css等)重寫並且不讓它第二次運行來阻止它。

讓你的規則是這樣的:

RewriteEngine On 
RewriteBase /~ps0ke/ 

# avoid any rules for resources and 2nd time: 
RewriteCond %{REQUEST_FILENAME} -d [OR] 
RewriteCond %{REQUEST_URI} \.(?:jpe?g|gif|bmp|png|tiff|css|js)$ [NC,OR] 
RewriteCond %{ENV:REDIRECT_STATUS} 200 
RewriteRule^- [L] 

# Serve index.html via cms.php when base dir or index.html is requested. Also 
# set the language. 
RewriteRule ^((en)/)?(index.html)?$ cms.php?lang=$2&path=index.html [NC,L,QSA] 

# Serve everything else via cms.php. Also set the language. 
# Serving from the page subdirectory is due to a problem with all-wildcard 
# RewriteRule. This might be fixed. 
RewriteRule ^((en)/)?(.*)$ cmas.php?lang=$2path=$3 [NC,L,QSA] 
+0

謝謝你這樣做主要是我需要的。我有兩個額外的請求:第一:有沒有辦法讓服務的任何類型的文件沒有明確提到它的擴展名在.htaccess?當我評論出特定的行時,一切都按預期工作,但圖像服務。我的腳本能夠提供二進制數據,所以不需要明確指定。 – Ps0ke 2014-10-27 23:22:19

+0

第二件事是:當請求指向目錄的URL時(儘管index.html被默默地提供),我得到某種類型的重定向。我的鏈接始終指向乾淨的網址'/〜ps0ke/tests/image /',但是使用Chrome或Firefox登錄到像'/〜ps0ke/tests/image /?lang =&path = tests%2fimage'這樣的頁面。我真的不知道這可能來自哪裏,使用'curl - head'不會顯示任何重定向頭。如果你有一個想法如何解決這個問題,那就太棒了。我想隱藏最終用戶的醜陋實現。 – Ps0ke 2014-10-27 23:30:31

+0

確定檢查我的編輯現在目錄重寫問題將得到解決。在新的瀏覽器中測試。另外我建議不要從評論中添加新的要求。 – anubhava 2014-10-28 05:57:28