2013-05-26 96 views
6

我一直在瀏覽symfony2框架源碼。在他們的例子網站htaccess文件,我發現寫的%{REQUEST_URI}::$1如下:

RewriteCond %{REQUEST_URI}::$1 ^(/.+)(.+)::\2$ 
RewriteRule ^(.*) - [E=BASE:%1] 

該規則上面的註釋說明

下重寫所有其他查詢到前端控制器。該條件可以確保如果您使用Apache別名來執行大容量虛擬主機,基本路徑將被預先設置爲允許正確解析app.php文件;它也可以在無鋸齒的環境中工作,從而提供一種安全的,單一尺寸的解決方案。

但是,這並不能解釋::$1::\2

他們是反向引用?如果不是,它們是什麼?他們的目的是什麼?

+0

完全同意,這是更好的措辭和簡潔,感謝trojansdestroy! –

回答

10

我在我的Zend項目中遇到了幾乎相同的htaccess文件,這裏是我的想法,希望它有幫助。

htaccess的文件(位於Zend的項目目錄,一樣的index.php)說

的RewriteCond%{REQUEST_URI} :: $ 1→(/.+)(+):: \ 2 $

(。*)

重寫規則^ $ - [E = BASE:%1]

重寫規則^(。*)$%{ENV:BASE}的index.php [NC,L]

假設的Zend安裝在http://mydomain.com/zend(稍後我們將其稱爲您的域名) 並且我們正在請求您的域名/ mycontroller/myaction

因此%{REQUEST_URI}將是「/ zend/mycontroller/myaction」。

請注意,$ 1是htaccess context [1]中RewriteRule指令中的模式,「在刪除將服務器導向當前RewriteRule的前綴後,最初將與文件系統路徑匹配(例如」 app1/index.html「或」index.html「,具體取決於指令的定義)」。

因此1美元將是「mycontroller/myaction」。

%{REQUEST_URI} :: $ 1將爲「/ zend/mycontroller/myaction :: mycontroller/myaction」。

上述字符串將與^(/.+)(。+):: \ 2 $匹配。請注意,對於圓括號中的兩個捕獲組,即(/.+)(.+):: many組合之前的兩個捕獲組可以匹配。例如:

組1:/ Z

組2:端/ myController的/ myaction

組1:/ Zend的/ myController的/ myactio

組2:N

之間的任何事情都是有效的匹配。事實上,最有趣的一個將是

組1:/ Zend的/

組2:myController的/ myaction

其中(是唯一的情況下),使反向引用\ 2(後::)到第二組一場比賽。

在這種情況下,「/ zend /」將被存儲在第一個RewriteRule所做的環境變量BASE中。 %1指的是RewriteCond中第一個匹配的字符串,即「/ zend /」。

看看第二個RewriteRule,很清楚爲什麼需要這個。由於index.php只能在/zend/index.php中找到,我們需要在index.php前添加「/ zend /」。

這裏我們假設使用URL路徑作爲替代第二個RewriteRule指令。請參閱[1],然後在RewriteRule指令部分下搜索「DocumentRoot相對於要服務的資源的路徑」。

以上所有內容使查詢字符串保持不變/不變。這取決於index.php如何解析查詢字符串(以及URI)。

最後是Zend安裝在域根目錄下的情況。

%{REQUEST_URI}將是「/ mycontroller/myaction」。 $ 1將是「mycontroller/myaction」。

要通過RewriteCond匹配的字符串將是「/ mycontroller/myaction :: mycontroller/myaction」。

這次(/.+)(.+)中的第二個組永遠不會匹配「mycontroller/myaction」,因爲在第一個組的第一個反斜槓後需要至少有一個字母,使第二個組爲關閉爲「ycontroller/myaction」,但不完全是「mycontroller/myaction」,因此無法匹配。

因此,不使用第一個RewriteRule。 BASE環境變量不會被設置,並且當第二個RewriteRule使用它時,它將只是空的。

參考

[1] http://httpd.apache.org/docs/current/mod/mod_rewrite.html

+0

這實際上聽起來是一個非常好的演繹它的作用和它的工作原理,我會更詳細地看看它,但我認爲你已經明白了。非常感謝! –

4

$1%{REQUEST_URI}::$1引用RewriteRule指令,即匹配的字符串,的.*^(.*)匹配的字符串。因此,%{REQUEST_URI}::$1被擴展爲由用戶提供的請求的URI路徑,以及由::分隔的當前內部URI路徑和查詢。

圖案^(/.+)(.+)::\2$用於查找的前綴,這使得剩餘部分的後面::部分匹配(\2是背面參照第二捕獲組的圖案的匹配的字符串)(第一拍攝組)。

如果這樣的發現匹配,該前綴存儲在環境變量BASE[E=BASE:%1],其中%1引用先前成功RewriteCond圖案匹配的匹配的字符串)。

+0

ahhh,謝謝你的解釋,我有一個想法,就是確定它是系統中的「安裝」目錄,相對於文檔根目錄。所以如果你在「domain.com/」安裝它,那麼$ 1將是「/」,$ 2將是「空的」,但是如果你在「domain.com/install/directory/application/route」安裝它,$ 1將會是「/安裝/目錄/」和$ 2將是「/應用程序/路線」 如果你明白爲什麼,你能爲我澄清?因爲我不是100%確定爲什麼他們需要兩個捕獲組,你可以用一個例子擴大你的答案? –

+0

嗯,我想我誤解了它在做什麼,事實上,它似乎只是設置一個環境變量/不管我打開了什麼網址,我創建了一個測試網站,它永遠不會改變,它總是/。我認爲他們已經發現了一種自動分配網站文檔根目錄的方式,無需手動分配。 –