apache mod_rewrite 가능성에 관계없이 하나의 규칙을 작성합니다.
-
02-07-2019 - |
문제
상당히 큰 웹사이트를 구축 중인데 .htaccess가 약간 부풀어 오르기 시작했습니다. 현재 시스템을 대체할 수 있는 방법이 있습니까? 전달할 수 있는 각 변수 수에 대해 하나의 규칙을 하나의 규칙으로 대체할 수 있습니까? 다양한 수의 입력을 설명할 수 있는 표현식?
예를 들어 나는 현재 다음을 가지고 있습니다:
RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4&$5=$6
RewriteRule ^([a-z]+)/([^/]*)/([^/]*)/([^/]*)$ /index.php?mode=$1&id=$2&$3=$4
RewriteRule ^([a-z]+)/([^/]*)$ /index.php?mode=$1&id=$2
RewriteRule ^([a-z]+)$ /index.php?mode=$1
첫 번째 역참조는 항상 방법 (더 이상 존재하는 경우) 두 번째는 항상 ID, 그 이후에는 입력 이름과 값 사이에서 추가 역참조가 번갈아 나타납니다.
http://www.example.com/search
http://www.example.com/search/3039/sort_by/name_asc/page/23
나는 모든 입력을 우아하게 처리하기 위해 하나의 표현식을 가질 수 있기를 바랍니다.
해결책
Drupal을 좋아하세요:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?q=$1 [L,QSA]
그런 다음 다음과 같은 PHP 코드를 사용하여 스크립트의 모든 항목을 처리합니다.
$pathmap = ();
if ($_GET["q"]){
$path = split("/", $_GET["q"]);
for ($i=0; $i+1<count($path); $i++){
$pathmap[$path[$i]] = $path[$i+1];
$i++;
}
}
다른 팁
단일 표현식으로 수행할 수 있는지는 모르겠지만 쿼리 문자열의 길이에 관계없이 고정된 개수의 표현식으로 수행할 수 있습니다.
mod_rewrite 규칙은 반복적으로 호출되어 때때로 mod_rewrite 재귀라고 불리는 기능을 제공합니다.피하는 기술이 있는데 그걸 써보고 싶다는 생각이 드네요.
마지막 쌍을 name=value&로 바꾸는 규칙을 설정합니다.
입력 쿼리 문자열을 출력에 계속 추가합니다.매번 쿼리 문자열은 길어지고 URL은 짧아집니다.
결국 마지막 규칙과 일치하는 값은 하나만 갖게 됩니다.
다음을 사용하여 쿼리 문자열을 캡처해야 합니다.
RewriteCond %{QUERY_STRING} ^(.*)$
그런 다음 %1을(를) 사용하여 출력에 다시 추가합니다.
결국 네 줄이 됩니다.
네 줄로 시작했다는 것은 알지만, 다섯 번째 줄을 추가하지 않고도 원하는 만큼 많은 매개변수를 일치시킬 수 있습니다.
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^(.*/)([^/]+)/([^/]+) $1?$2=$3&%1 [L]
RewriteCond %{QUERY_STRING} ^(.*)$
RewriteRule ^([^/]+)/ $1.php?%1 [L]
그러면 다음 내용이 다시 작성됩니다.
/mypage/param1/val1/param2/val2/param3/val3/... --->
/mypage.php?param1=val1¶m2=val2¶m3=val3&...
매개변수가 하나만 남으면 중지됩니다.첫 번째 "매개변수"를 취하고 해당 이름으로 .php 파일을 호출합니다.param/val 쌍의 수에는 제한이 없습니다.
나는 그것이 방법이라고 믿지 않습니다. 그러나 가장 좋은 방법은 너무 많은 역 참조를 수행하는 대신 "index.php" 스크립트가 경로를 처리하도록 하는 것입니다.
예를 들어, 재작성은 다음과 같습니다.
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
아니면 비슷한...그러면 $_SERVER['REQUEST_URI'] 변수에 분할 및 구문 분석이 가능한 경로 정보가 포함됩니다.
$path = split('/', $_SERVER['REQUEST_URI']);
array_shift($path); // We always have a first null value
$mode = array_shift($path);
이는 모드를 포함하는 $mode와 경로의 나머지 요소인 요소 배열을 포함하는 $path로 끝납니다.
http://example.com/foo/bar/baz
$mode는 'foo'이고 $path는 'bar'와 'baz'를 포함하는 배열이 됩니다.