2014-01-22 64 views
2

我正在使用mod_rewrite創建規範鏈接。到目前爲止,我已經使用RewriteRule成功地滿足了每個測試用例。下面的代碼絕對有效,並且可以適用。但是,我知道這些重寫可能會導致稅收,所以我想盡可能提高效率。哪裏可以提高效率?什麼使重寫效率降低或效率低下?優化mod_rewrite

該網站有3個不同的區域:國家,州和學校。每個地區的主頁都是整個地區的中心。例如,「州」提供了所有50個州的名單。

國家地區:

  • url.com/state/產生默認年
  • url.com/state/所有50個州的列表(R =狀態) GA/爲默認年份生成GA列表(r = GA
  • url.com/state/2011生成列表o ˚F所有50個州(R =狀態)爲2011(類= 2011
  • url.com/state/GA/2011產生用於GA列表(R = GA)爲2011( 類= 2011

國家區域:

  • url.com/national/產生NAT有理上市(R =國家)默認年
  • url.com/national/jobs/產生全國上市(R =國家)的默認工作(顯示=工作)今年
  • url.com/national/2011產生全國上市(R =國家)2011年(類= 2011
  • url.com/nationa L /職位/ 2011產生全國上市的工作(顯示=工作)2011年(R =國家)(類= 2011

校區:

不幾乎與國家名單一樣,但還有一個子變量。

<IfModule mod_rewrite.c> 
RewriteEngine on 
# Rewrite user URLs 
RewriteRule ^state/?$ index.php?r=state [L,NC] 
RewriteRule ^state/([0-9]+)/?$ index.php?r=state&class=$1 [L,NC] 
RewriteRule ^state/([A-Za-z]+)/?$ index.php?r=$1 [L,NC] 
RewriteRule ^state/([A-Za-z]+)/([0-9]+)/?$ index.php?r=$1&class=$2 [L,NC] 
RewriteRule ^national/?$ index.php?r=national [L,NC] 
RewriteRule ^national/([0-9]+)/?$ index.php?r=national&class=$1 [L,NC] 
RewriteRule ^national/([A-Za-z]+)/?$ index.php?r=national&show=$1 [L,NC] 
RewriteRule ^national/([A-Za-z]+)/([0-9]+)/?$ index.php?r=national&show=$1&class=$2 [L,NC] 
RewriteRule ^schools/?$ index.php?r=schools [L,NC] 
RewriteRule ^schools/([0-9]+)/?$ index.php?r=schools&class=$1 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/?$ index.php?school=$1 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([0-9]+)/?$ index.php?school=$1&class=$2 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&class=$3 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&sub=$3&class=$4 [L,NC] 
</IfModule> 

在此先感謝。如果更多細節會有所幫助,我會更新/回覆。

回答

2

任何形式的優化都需要在你的php腳本中進行「空白」檢查,因爲不在那裏的路徑仍然會有一個$_GET['']變量與之相關聯,只是它會變成空白。

至於「國家」和「民族」的網址去,有相當多的只有一件事可以做,結合這兩個規則:通過將「類」可選

RewriteRule ^state/([A-Za-z]+)/?$ index.php?r=$1 [L,NC] 
RewriteRule ^state/([A-Za-z]+)/([0-9]+)/?$ index.php?r=$1&class=$2 [L,NC] 

(但有將仍然是一個 「類」 參數,它只會爲空):

RewriteRule ^state/([A-Za-z]+)(?:/([0-9]+)|)/?$ index.php?r=$1&class=$2 [L,NC] 

同樣與國家:

RewriteRule ^national/([A-Za-z]+)/?$ index.php?r=national&show=$1 [L,NC] 
RewriteRule ^national/([A-Za-z]+)/([0-9]+)/?$ index.php?r=national&show=$1&class=$2 [L,NC] 

合併成:

RewriteRule ^national/([A-Za-z]+)(?:/([0-9]+)|)/?$ index.php?r=national&show=$1&class=$2 [L,NC] 

但是學校的東西有點複雜。您可以將其中的一些,如:

RewriteRule ^schools/([A-Za-z-]+)/?$ index.php?school=$1 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC] 

可以組合成只是一個單一的:

RewriteRule ^schools/([A-Za-z-]+)(?:/([A-Za-z]+)|)(?:/([A-Za-z]+)|)/?$ index.php?school=$1&show=$2&sub=$3 [L,NC] 

RewriteRule ^schools/([0-9]+)/?$ index.php?r=schools&class=$1 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([0-9]+)/?$ index.php?school=$1&class=$2 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&class=$3 [L,NC] 
RewriteRule ^schools/([A-Za-z-]+)/([A-Za-z]+)/([A-Za-z]+)/([0-9]+)/?$ index.php?school=$1&show=$2&sub=$3&class=$4 [L,NC] 

可以組合成一個單一的:

​​
+0

'^重寫規則狀態/ (([A-Za-z] +)/)?(([0-9] +)/)?$ /index.php?r = $ 2&class = $ 4'必須執行該操作, 對?你可以爲其他網站做類似的事情。 – Sumurai8

+0

@ Sumurai8問題是如果中間路徑丟失,「r」變成「狀態」 –

+0

這是非常有幫助的。感謝您抽出寶貴的時間,Jon。我已經測試了您的解決方案,並且工作完美無瑕。 (我應該補充說,如果沒有任何內容傳遞,php腳本已經爲每個_GET設置了默認值。) –

0

你可以爲每個3創建一個大的正則表達式頁面,但是如果實際上使事情變得更快或更慢,您將不得不對其進行測試。如果Apache必須在可以提供頁面之前應用更多的正則表達式,速度會更慢,但是如果它必須對url應用複雜的正則表達式,則可能比將幾個簡單的正則表達式應用於相同的url更慢。 Mod_rewrite比大多數編程語言更快地進行url重寫,主要是因爲重寫url,所以不需要加載任何解釋器/編譯器。

如果你能夠使用,而不是L標誌END標誌,這將加快重寫了一下,因爲不像L標誌,該標誌END將完全停止重寫,不只是這種重寫的「圓」。然而,它不適用於舊版本的Apache。

但是,您重定向所有請求到index.php,所以有如下規則:

RewriteCond %{REQUEST_FILENAME} !-f 
RewriteCond %{REQUEST_FILENAME} !-d 
RewriteRule^/index.php [L] 

然後檢查$_SERVER['REQUEST_URI'],例如像這樣:

$boom = explode('/', $_SERVER['REQUEST_URI']); 
#var_dump($boom); //Something like Array('', 'state', '2011'); 
if(isset($boom[1])) { 
    if($boom[1] == 'state') { 
    if(isset($boom[3])) { 
     $r = $boom[2]; 
     $class = $boom[3]; 
    } else if(isset($boom[2]) && intval($boom[2], 10) == $boom[2]) { 
     $r = 'state'; 
     $class = $boom[2]; 
    } else if(isset($boom[2])) { 
     $r = $boom[2]; 
    } else { 
     $r = 'state'; 
    } 
    } else if($boom[1] == 'schools') { 
    echo 'a'; 
    } 
} else { 
    header('404: What the heck is this?!'); 
    //No, don't use this header... 
} 
+0

謝謝你的建議,尤其是L vs End建議。我會試着弄清楚我的apache版本是否支持End。 –