我有 htaccess 檔案,其中有這樣的內容:
RewriteRule ^((en|us|uk|fr|de)/)?([0-9\-.] );([0-9\-.] )$ index.php?l=$2&t=$3;$4 [QSA,L]
RewriteRule ^((en|us|uk|fr|de)/)?([A-Za-z\-] )$ index.php?l=$2&t=$3 [QSA,L]
和許多類似的行。此外,在所有規則中,語言可能根本不存在。
我可以以某種方式將語言串列(en|us|uk|fr|de)放入一個變數中并只使用這個變數嗎?使用當前的方法,添加新語言意味著重寫許多規則。
uj5u.com熱心網友回復:
我可以以某種方式將語言串列
(en|us|uk|fr|de)放入一個變數中并只使用這個變數嗎?
您不能直接在正則運算式中使用“變數”,因為 Apache 使用的正則運算式引擎 (PCRE) 不支持這種型別的語法。
您可以改為使正則運算式更通用并匹配任何 2 個小寫字母并依靠您的應用程式來驗證語言代碼(無論如何您都應該這樣做)。然后,您在添加新語言時根本不需要更新您的 Apache 配置(這將是更可取的)。例如:
RewriteRule ^(([a-z]{2})/)?([0-9\-.] );([0-9\-.] )$ index.php?l=$2&t=$3;$4 [QSA,L]
此外...如果您沒有任何其他可以合法地將 2 個小寫字母作為第一個路徑段的非語言 URL,那么您也可以在 中驗證這一點.htaccess,并在現有語言規則之前使用附加規則。例如:
# Validate language code in first path segment
RewriteCond $1 !^(en|us|uk|fr|de)$
RewriteRule ^([a-z]{2})/ - [R=404]
上述規則規定...如果在第一個路徑段中傳遞了 2 個小寫字母,并且這 2 個字符序列與所述語言代碼中的一個不匹配,則觸發 404。不處理后續規則。
這允許您在檔案頂部僅宣告一次有效的語言代碼。但這確實限制了您的 URL 結構(沒有額外的規則/條件),因為您不能擁有不是語言代碼形式/xx/...的URL。xx
更新:使用“變數”...
再考慮一下......您可能會使用“變數”,但您需要向每個規則添加一個條件(RewriteCond指令),以便將請求的 URL 路徑中的語言代碼與“串列”進行比較" 的(環境)變數中的語言代碼。
例如:
# Define "list" of valid language codes
RewriteRule ^ - [E=LANG_CODES:en|us|uk|fr|de]
RewriteCond %{ENV:LANG_CODES}@$2 ([a-z]{2}).*@\1?$
RewriteRule ^(([a-z]{2})/)?([0-9\-.] );([0-9\-.] )$ index.php?l=$2&t=$3;$4 [QSA,L]
分配給LANG_CODES環境變數的值只是由任何唯一字符分隔的語言代碼字串。我使用管道(豎線)作為分隔符,就像正則運算式交替一樣,但這不是正則運算式。
正則運算式([a-z]{2}).*@\1?$使用內部反向參考 ( \1) 將 URL 路徑中傳遞的語言代碼與LANG_CODES字串中的語言代碼相匹配。額外的復雜性是可能根本沒有語言代碼(因此需要尾隨?$)。這個正則運算式不是特別有效,因為它可能涉及大量回溯(盡管在這種情況下這是一個相對較小的問題)。
不用說,如果你有很多規則,這可能會增加很多“臃腫”。如果重寫引擎發生任何“回圈”,則使用 env var 可能會出現問題,因為 env var 可能被“重命名”(可能需要修改其他規則以允許這樣做或完全防止回圈)。
這種“更新”實際上只是出于“學術”的興趣(盡管它確實避免了與恰好具有僅由兩個字符組成的初始路徑段的任何非語言 URL 沖突)。我上面提出的第一個解決方案會更好。
另外:我會讓RewriteRule 模式中的第一組不捕獲,然后語言代碼將在$1反向參考中可用,而不是$2. 例如:
RewriteRule ^(?:([a-z]{2})/)?([0-9\-.] );([0-9\-.] )$ index.php?l=$1&t=$2;$3 [QSA,L]
作為一般規則,您感興趣的第一個正則運算式組之前的任何正則運算式組都應該是非捕獲的,因此您捕獲的感興趣的組總是 start $1。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/523399.html
