2013-12-15 62 views
1

我正在使用MAMP和基於虛擬主機的安裝程序創建一個用於處理的'.dev'tld。 我的網站的.htaccess使用了mod_rewrite像這樣:來自REQUEST_FILENAME的奇怪行爲?

RewriteEngine on 
RewriteBase/

RewriteCond %{REQUEST_FILENAME} !-d 
RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME}\.php -f 

RewriteRule ^(.*)$ $1.php [L] 
RewriteRule ^(butchers|news|recipes)/([a-zA-Z0-9-/]+)$ /$1.php?s=$2 [L,QSA] 

我的網站提供的肉店的目錄。列表視圖顯示爲butchers.php,可通過butchers訪問。詳細視圖顯示爲butchers.php?s=some-butcher-name,請訪問butchers/some-butcher-name。 正如你所看到的,同樣的機制適用於新聞和食譜部分。

好的,這裏的東西:這用於工作。它工作得很好,然後在升級MAMP後我重啓了我的系統,現在它給了我一個內部服務器錯誤。我假設我已經從Apache 1.x轉到2.x;我不得不在升級後重做我的虛擬主機配置,但其他一切都是香草(與上次相同),但我禁用了MultiViews。 mod_rewrite的日誌看起來像這樣(截斷第幾列)

[perdir /Users/myusername/Sites/dev/sitename/] add path info postfix: /Users/myusername/Sites/dev/sitename/butchers -> /Users/myusername/Sites/dev/sitename/butchers/example-butcher 
[perdir /Users/myusername/Sites/dev/sitename/] strip per-dir prefix: /Users/myusername/Sites/dev/sitename/butchers/example-butcher -> butchers/example-butcher 
[perdir /Users/myusername/Sites/dev/sitename/] applying pattern '^(.*)$' to uri 'butchers/example-butcher' 
[perdir /Users/myusername/Sites/dev/sitename/] RewriteCond: input='/Users/myusername/Sites/dev/sitename/butchers' pattern='!-d' => matched 
[perdir /Users/myusername/Sites/dev/sitename/] RewriteCond: input='/Users/myusername/Sites/dev/sitename/butchers' pattern='!-f' => matched 
[perdir /Users/myusername/Sites/dev/sitename/] RewriteCond: input='/Users/myusername/Sites/dev/sitename/butchers.php' pattern='-f' => matched 
[perdir /Users/myusername/Sites/dev/sitename/] rewrite 'butchers/example-butcher' -> 'butchers/example-butcher.php' 
[perdir /Users/myusername/Sites/dev/sitename/] add per-dir prefix: butchers/example-butcher.php -> /Users/myusername/Sites/dev/sitename/butchers/example-butcher.php 
[perdir /Users/myusername/Sites/dev/sitename/] trying to replace prefix /Users/myusername/Sites/dev/sitename/ with/
strip matching prefix: /Users/myusername/Sites/dev/sitename/butchers/example-butcher.php -> butchers/example-butcher.php 
add subst prefix: butchers/example-butcher.php -> /butchers/example-butcher.php 
[perdir /Users/myusername/Sites/dev/sitename/] internal redirect with /butchers/example-butcher.php [INTERNAL REDIRECT] 

這裏是我發生了什麼事的理解:

  • 我UA詢問butchers/example-butcher
  • 當REQUEST_FILENAME在的RewriteCond使用,輸出路徑只有butchers而不是butchers/example-butcher
  • 這就通過了,因爲butchers.php是真實的
  • 重寫被允許追加「.PHP」,具體根據重寫規則
  • 當追加,它其追加到原始請求butchers/example-butcher
  • 的內部重定向重新啓動循環與butchers/example-butcher.php

然後進程再次啓動相同的問題 - 即RewriteCond測試這個奇怪的不完整版本的路徑,但運行在正確的路徑。出現這種情況的十倍,積累了越來越多的.php的,阿帕奇打了極限,發出500

  • 要求butchers/example-butcher
  • butchers.php一個真正的文件之前?是!
  • 追加.php
  • 要求butchers/example-butcher.php
  • butchers.php一個真正的文件?是!
  • 追加.php
  • 要求butchers/example-butcher.php.php
  • ...等

所以,我可以看到爲什麼有環路,爲什麼它要不斷增加.php本身,我只是不明白爲什麼REQUEST_FILENAME永遠只給出了路徑的第一級。我找不到任何說明這是規定行爲的文檔。

任何想法?我已經燒了整個工作日對此:/

謝謝!

回答

0

原因是因爲%{REQUEST_FILENAME}變量不是簡單地將請求的URI映射到單個文件/目錄。當你有一個這樣的請求:

/foo/bar/something 

和你有這兩個文件:

/foo.php 
/foo/bar.php 
/foo/bar/something.php 

的情況:因爲mod_rewrite的也佔PATH_INFO

RewriteCond %{REQUEST_FILENAME}.php -f 

將是真正的。如果你有這些php文件中的一個,那麼mod_rewrite會嘗試聰明,並確定請求的URI實際上是否在請求的URI路徑中,並添加到路徑節點而不是最後。至嚴格檢查請求是否存在+ .php,您需要做:

RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI}.php -f