Apache RewriteRule 명령어로 환경변수를 설정할 때 변수 이름 앞에 "REDIRECT_"가 붙는 원인은 무엇입니까?
Apache 환경변수(PHP에서 사용)를 설정하려고 합니다.[E=VAR:VAL]
.htaccess 파일의 RewriteRule 규칙에 플래그를 지정합니다.
PHP에서 변수가 서버 변수로 액세스되는 것을 이미 발견했습니다.$_SERVER
보다는$_ENV
(그건 어느 정도 말이 돼요)하지만, 내 문제는 몇 가지 규칙 때문에[E=VAR:VAL]
플래그가 예상대로 작동하여 변수가 됩니다.$_SERVER['VAR']
하지만 다른 규칙에서는 변수로 끝납니다.$_SERVER['REDIRECT_VAR']
또는$_SERVER['REDIRECT_REDIRECT_VAR']
,기타
A. Apache에서 환경변수를 설정하는 원인[E=VAR:VAL]
변수 이름 앞에 "REDIRECT_"를 추가하여 이름을 변경하는 플래그
B. 이름이 변경되지 않은 환경변수로 끝나도록 하려면 어떻게 해야 합니까? 그러면 PHP에서 환경변수에 액세스할 수 있습니다.$_SERVER['VAR']
변수 이름 앞에 REDIRECT_ 인스턴스가 하나 이상 추가되어 있는지 확인할 필요가 없습니다.
부분 솔루션이 발견되었습니다.개서 규칙의 선두에 다음 항목을 추가하면 원래 ENV가 다시 생성됩니다.각 리다이렉트 상의 VAR(필요한 경우 REDIRECT_VAR 버전도 그대로)
RewriteCond %{ENV:REDIRECT_VAR} !^$
RewriteRule .* - [E=VAR:%{ENV:REDIRECT_VAR}]
이 동작은 유감이며 문서화되어 있지 않은 것 같습니다.
.htaccess per-s
에서 일어나는 일은 다음과 같습니다..htaccess
디렉토리 단위(패키지 단위) 컨텍스트:
Apache가 처리한다고 가정합니다..htaccess
파일에는 개서 지시가 포함되어 있습니다.
-
Apache는 표준 CGI/Apache 변수를 모두 사용하여 환경 변수 맵을 채웁니다.
-
개서 개시
-
환경변수는 다음과 같이 설정됩니다.
RewriteRule
지시. -
Apache가 다음 작업을 중지하는 경우
RewriteRule
지시(이유)L
flag 또는 규칙 집합의 끝) 및 URL이 에 의해 변경되었습니다.RewriteRule
Apache는 요청 처리를 재시작합니다.이 부품이 익숙하지 않은 경우 플래그 설명서를 참조하십시오.
따라서 규칙 집합은 처음부터 다시 실행될 수 있습니다.일반적으로 이 문제는 규칙 중 하나가 내부 또는 외부로 리다이렉트하여 요청 프로세스를 다시 시작할 때 발생합니다.
-
제가 관찰한 바로는, 4번, 1번 반복이 되면, 그 다음에 환경변수가 설정된다고 생각합니다.
RewriteRule
지시문은 앞에 붙는다REDIRECT_
환경 변수 맵에 추가(순서는 아니지만 해당 조합으로 구성된 최종 결과).이 단계에서는 선택한 변수 이름이 지워집니다. 잠시 후에 이것이 왜 중요하고 불편한지에 대해 설명하겠습니다.
변수 이름 복원
처음 이 문제에 부딪혔을 때, 저는 다음과 같은 일을 하고 있었습니다..htaccess
(증명):
RewriteCond %{HTTP_HOST} (.+)\.projects\.
RewriteRule (.*) subdomains/%1/docroot/$1
RewriteRule (.+/docroot)/ - [L,E=EFFECTIVE_DOCUMENT_ROOT:$1]
처음에 환경변수를 설정했을 경우RewriteRule
Apache는 재작성 프로세스를 재시작하고 변수 앞에REDIRECT_
(위의 4단계와 5단계) 따라서 할당한 이름으로 액세스 할 수 없게 됩니다.
이 경우, 첫 번째RewriteRule
URL 을 변경하기 때문에, 양쪽 모두RewriteRule
가 처리되고 Apache가 절차를 재시작하여 처리한다..htaccess
두 번째, 두 번째, 첫 번째RewriteRule
에 의해 건너뜁니다.RewriteCond
지시적인데, 두 번째는RewriteRule
일치시키고 환경변수를 다시 설정하며 URL을 변경하지 않습니다.따라서 요청/재작성 프로세스가 다시 시작되지 않고 선택한 변수 이름이 그대로 유지됩니다.이 경우엔 사실 둘 다 가지고 있어요REDIRECT_EFFECTIVE_DOCUMENT_ROOT
그리고.EFFECTIVE_DOCUMENT_ROOT
를 사용하면,L
선두에 서다RewriteRule
, 나는 단지EFFECTIVE_DOCUMENT_ROOT
.
@trowel의 부분 솔루션도 마찬가지로 동작합니다.재작성 지시어는 다시 처리되고 이름이 변경된 변수는 원래 이름으로 다시 할당되며 URL이 변경되지 않으면 프로세스가 종료되고 할당된 변수 이름이 고정됩니다.
왜 그 기술들이 불충분한가
이 두 기술 모두 중대한 결함이 있습니다.즉, 개서 규칙이 다음과 같습니다..htaccess
환경변수를 설정하는 파일은 URL을 보다 깊이 중첩된 디렉토리로 고쳐 씁니다..htaccess
파일을 다시 작성하면 할당된 변수 이름이 다시 지워집니다.
다음과 같은 디렉토리 레이아웃이 있다고 가정합니다.
docroot/
.htaccess
A.php
B.php
sub/
.htaccess
A.php
B.php
그리고...docroot/.htaccess
다음과 같습니다.
RewriteRule ^A\.php sub/B.php [L]
RewriteRule .* - [E=MAJOR:flaw]
그래서 네가 부탁하는 거야/A.php
, 그리고 그것은 로 고쳐졌습니다.sub/B.php
넌 아직 네 능력을 가지고 있어MAJOR
변수.
다만, 에 개서 지시가 있는 경우는,docroot/sub/.htaccess
(단순히RewriteEngine Off
또는RewriteEngine On
), 고객님의MAJOR
변수는 사라집니다.그 이유는 URL이 다음 주소로 다시 작성되면sub/B.php
,docroot/sub/.htaccess
처리되며, 개서 지시가 포함되어 있는 경우는, 에서 개서 지령을 개서합니다.docroot/.htaccess
다시 처리되지 않습니다.를 가지고 있는 경우REDIRECT_MAJOR
끝나고docroot/.htaccess
처리되었습니다(예를 들어, 를 생략했을 경우).L
처음부터 깃발RewriteRule
)는 아직 사용할 수 있지만 선택한 변수 이름을 설정하기 위해 이러한 지시어가 다시 실행되지 않습니다.
상속
예를 들어 다음과 같습니다.
-
환경 변수를 설정하다
RewriteRule
디렉토리 트리의 특정 레벨에서의 지시(예:docroot/.htaccess
) -
보다 상세한 레벨의 스크립트로 사용할 수 있도록 한다.
-
그것들을 할당된 이름으로 이용할 수 있게 하다
-
보다 깊이 내포된 명령어를 다시 쓸 수 있다
.htaccess
파일
가능한 해결책은 다음과 같습니다.RewriteOptions inherit
보다 깊이 내포된 지시..htaccess
이를 통해 깊이 중첩되지 않은 파일에서 다시 쓰기 명령을 실행하고 위에서 설명한 기술을 사용하여 선택한 이름으로 변수를 설정할 수 있습니다.단, 보다 깊이 중첩된 디렉토리에서 다시 실행할 때 문제가 발생하지 않도록 덜 중첩된 파일에서 다시 쓰기 지시어를 작성하려면 더 신중해야 하기 때문에 복잡성이 증가합니다.Apache는 보다 깊이 중첩된 디렉토리의 dir 단위 접두사를 삭제하고 해당 값에 대해 덜 중첩된 파일에서 다시 쓰기 명령을 실행한다고 생각합니다.
@trowel의 기술
제가 보기엔 다음과 같은 구조를 사용할 수 있습니다.%{ENV:REDIRECT_VAR}
가치 요소에서RewriteRule
E
플래그(예:[E=VAR:%{ENV:REDIRECT_VAR}]
)은 문서화되어 있지 않은 것 같습니다.
VAL은 전개되는 백레퍼런스($N 또는 %N)를 포함할 수 있습니다.
정상적으로 동작하고 있는 것 같습니다만, 문서화되어 있지 않은 것에 의존하는 것을 피하고 싶은 경우(잘못하고 있는 경우는 정정해 주세요)는, 다음의 방법으로 간단하게 실시할 수 있습니다.
RewriteCond %{ENV:REDIRECT_VAR} (.+)
RewriteRule .* - [E=VAR:%1]
EnvIf 설정
이것은 문서화된 동작(아래 참조)과 일치하지 않는 것 같기 때문에 이것을 사용하는 것을 권장하지 않습니다.docroot/.htaccess
(Apache 2.2.20)을 사용하면 다음과 같습니다.
SetEnvIf REDIRECT_VAR (.+) VAR=$1
이 방법으로 테스트할 수 있는 것은 이전의 SetEnvIf [NoCase]지침에서 정의된 환경변수뿐입니다.
왜요?
이 이름들에 접두사를 붙이는 이유가 뭔지 모르겠어요REDIRECT_
mod_rewrite 지시어, 플래그 또는 환경변수에 대해서는 Apache 문서 섹션에 기재되어 있지 않은 것 같기 때문에 그다지 놀랄 일도 아닙니다.
지금으로서는, 지정명을 그대로 두는 것보다 왜 그것이 좋은지에 대한 설명이 없는 것은, 나에게 있어서 큰 폐가 되는 것 같습니다.문서화의 부족은 그것에 대한 나의 회의감을 조장할 뿐이다.
환경변수를 개서규칙으로 할당할 수 있는 것은 편리합니다.적어도 편리합니다.그러나 이러한 이름 바꾸기 행태로 인해 그 유용성은 크게 감소한다.이 투고의 복잡성은 이 행동과 그것을 극복하기 위해 뛰어넘어야 하는 후프가 얼마나 미친 것인지 보여준다.
나는 이것을 전혀 테스트하지 않았고 그것이 A나 B 포인트를 다루지 않는다는 것을 알지만, PHP 문서의 코멘트 및 이러한 변수에 액세스하기 위한 몇 가지 가능한 해결책에 이 문제에 대한 설명이 있습니다.$_SERVER['VAR']
:
http://www.php.net/manual/en/reserved.variables.php#79811
편집 - 제공된 질문에 대한 추가 답변:
A: 환경 변수가 리디렉션과 관련된 경우 Apache에 의해 이름이 변경됩니다.예를 들어 다음과 같은 규칙이 있는 경우:
RewriteRule ^index.php - [E=VAR1:'hello',E=VAR2:'world']
그런 다음 VAR1 및 VAR2에 액세스할 수 있습니다.$_SERVER['VAR1']
그리고.$_SERVER['VAR2']
다만, 페이지를 이렇게 리다이렉트 하면, 다음과 같이 됩니다.
RewriteRule ^index.php index2.php [E=VAR1:'hello',E=VAR2:'world']
그럼 다음 명령어를 사용해야 합니다.$_SERVER['REDIRECT_VAR1']
,기타.
B: 이 문제를 해결하는 가장 좋은 방법은 PHP를 사용하고 싶은 변수를 처리하는 것입니다.를 통해 실행되는 함수를 만듭니다.$_SERVER
필요한 항목을 찾을 수 있습니다.다음과 같은 기능을 사용할 수도 있습니다.
function myGetEnv($key) {
$prefix = "REDIRECT_";
if(array_key_exists($key, $_SERVER))
return $_SERVER[$key];
foreach($_SERVER as $k=>$v) {
if(substr($k, 0, strlen($prefix)) == $prefix) {
if(substr($k, -(strlen($key))) == $key)
return $v;
}
}
return null;
}
코드를 변경하고 싶지 않기 때문에(사용하는 라이브러리의 코드도 변경할 수 없기 때문에), 어플리케이션의 부트스트래핑(예:index.php
– 재작업합니다.$_ENV
변수 앞에 프레픽스를 붙일 수 있도록 superglobalREDIRECT_
는, 통상의 목적명으로 고쳐집니다.
// Fix ENV vars getting prepended with `REDIRECT_` by Apache
foreach ($_ENV as $key => $value) {
if (substr($key, 0, 9) === 'REDIRECT_') {
$_ENV[str_replace('REDIRECT_', '', $key)] = $value;
putenv(str_replace('REDIRECT_', '', $key) . '=' . $value);
}
}
직접 설정할 뿐만 아니라$_ENV
, 그러나 우리는 그것을 저장하기도 합니다.putenv()
기존 코드와 라이브러리– 이 방법에서는getenv()
– 정상적으로 동작합니다.
사이드노트: 헤더를 추출하는 경우 –HTTP_AUTHORIZATION
– 코드에서는, 같은 조작을 실시할 필요가 있습니다.$_SERVER
:
foreach ($_SERVER as $key => $value) {
if (substr($key, 0, 9) === 'REDIRECT_') {
$_SERVER[str_replace('REDIRECT_', '', $key)] = $value;
}
}
언급URL : https://stackoverflow.com/questions/3050444/when-setting-environment-variables-in-apache-rewriterule-directives-what-causes
'programing' 카테고리의 다른 글
MySQL에 IP 주소를 저장하는 가장 효율적인 방법 (0) | 2022.09.08 |
---|---|
MariaDB 업데이트 오류 내부 조인 및 선택 (0) | 2022.09.06 |
PHP의 십진수에서 불필요한 0자리 제거 (0) | 2022.09.06 |
switch 문에 열거를 사용하는 Java (0) | 2022.09.06 |
bash에서 .sql 스크립트를 실행하는 방법 (0) | 2022.09.06 |