Lors de la définition des variables d'environnement d'Apache directives RewriteRule, quelles sont les causes de la variable nom de préfixe “REDIRECT_”?
Je suis en train de mettre Apache variables d'environnement (pour une utilisation en PHP) avec le [E=VAR:VAL]
drapeau sur des règles de réécriture des règles .fichier htaccess.
J'ai déjà découvert les variables sont accessibles en PHP les variables de serveur $_SERVER
plutôt que $_ENV
(ce qui rend d'une certaine quantité de sens). Cependant, mon problème est que certaines règles de la [E=VAR:VAL]
indicateur fonctionne comme prévu et je me retrouve avec une variable $_SERVER['VAR']
mais pour les autres règles, je termine avec une variable $_SERVER['REDIRECT_VAR']
ou $_SERVER['REDIRECT_REDIRECT_VAR']
, etc
A. Quelles sont les causes d'une variable d'environnement d'Apache à l'aide de la [E=VAR:VAL]
drapeau pour obtenir renommé en ayant "REDIRECT_" préfixer le nom de la variable?
B. Que puis-je faire pour m'assurer que je me retrouve avec une Variable d'Environnement avec un même nom afin que je puisse y accéder en PHP comme $_SERVER['VAR']
sans avoir à recourir à la vérification des variations de la variable nom en avoir un de plus les instances de "REDIRECT_" ajouté à cela?
Solution partielle trouvée. Adjonction de ce qui suit le début de la réécriture des règles recrée l'original ENV:VAR sur chaque redirection (ainsi que de quitter le REDIRECT_VAR versions) s'ils sont nécessaires:
RewriteCond %{ENV:REDIRECT_VAR} !^$
RewriteRule .* - [E=VAR:%{ENV:REDIRECT_VAR}]
- J'ai toujours utiliser la fonction getenv() - php.net/manual/en/function.getenv.php et je n'ai pas encore eu de problèmes bizarres.
Vous devez vous connecter pour publier un commentaire.
Ce comportement est malheureux et n'apparaît même pas à être documentées.
.htaccess par-dir contexte
Voici ce qui semble arriver dans
.htaccess
de répertoire (par dir) contexte:Supposer que les processus Apache un
.htaccess
fichier qui comprend les réécrire directives.Apache remplit sa variable d'environnement carte avec tous de la norme CGI /Apache variables
La réécriture commence
Variables d'environnement sont définies dans
RewriteRule
directivesQuand Apache arrête le traitement de la
RewriteRule
directives (à cause d'unL
drapeau ou à la fin de la base de règles) et l'URL a été modifiée par unRewriteRule
, Apache redémarre le traitement de la demande.Si vous n'êtes pas familier avec cette partie, voir la
L
drapeau de la documentation:De ce que je peux observer, je crois que quand #4 qui se passe, #1 est répété, alors les variables d'environnement qui ont été mis en
RewriteRule
directives sont précédées deREDIRECT_
et ajoutée à l'environnement vars carte (pas nécessairement dans cet ordre, mais le résultat final composé de la combinaison).Cette étape est où le choisi les noms de variables sont effacées, et dans un instant je vais vous expliquer pourquoi c'est si important et gênant.
Restaurer les noms de variables
Quand je suis tombé sur cette question, je faisais quelque chose comme ce qui suit dans
.htaccess
(simplifié):Si je devais définir la variable d'environnement dans le premier
RewriteRule
, Apache doit reprendre le processus de réécriture et de la faire précéder de la variable avecREDIRECT_
(étapes #4 & 5 ci-dessus), donc je voudrais perdre l'accès à travers le nom que j'ai attribué.Dans ce cas, la première
RewriteRule
modifie l'URL, donc après les deuxRewriteRule
s sont traitées, Apache redémarrage de la procédure et des processus la.htaccess
de nouveau. La deuxième fois, la premièreRewriteRule
est ignorée en raison de laRewriteCond
directive, mais la deuxièmeRewriteRule
matches, définit la variable d'environnement (de nouveau), et, surtout, ne pas modifier l'URL. Si la demande /le processus de réécriture ne pas recommencer, et le nom de la variable, j'ai choisi de bâtons. Dans ce cas, j'ai effectivement deuxREDIRECT_EFFECTIVE_DOCUMENT_ROOT
etEFFECTIVE_DOCUMENT_ROOT
. Si je devais utiliser unL
drapeau sur la premièreRewriteRule
, j'avais seulement ontEFFECTIVE_DOCUMENT_ROOT
.@truelle partielle de la solution fonctionne de la même façon: la réécriture directives sont traitées à nouveau, le nouveau nom de la variable est attribuée à l'origine le nom de nouveau, et si l'URL ne change pas, le processus est terminé, et le affectée nom de la variable de bâtons.
Pourquoi ces techniques sont insuffisantes
Deux de ces techniques souffrent d'un défaut majeur: lorsque les règles de réécriture dans le
.htaccess
fichier où vous définissez les variables d'environnement de réécrire l'URL d'un plus profondément imbriqués répertoire qui a une.htaccess
fichier qui n'a aucune réécriture, votre nom de variable est effacé de nouveau.Dire que vous avez un annuaire de mise en page comme ceci:
Et un
docroot/.htaccess
comme ceci:Donc vous demander
/A.php
, et c'est réécrite poursub/B.php
. Vous avez encore votreMAJOR
variable.Toutefois, si vous avez des réécrire les directives en
docroot/sub/.htaccess
(même justeRewriteEngine Off
ouRewriteEngine On
), votreMAJOR
variable disparaît. C'est parce qu'une fois que l'URL est réécrite poursub/B.php
,docroot/sub/.htaccess
est traitée, et si elle contient tout réécrire les directives, la réécriture de directives dansdocroot/.htaccess
ne sont pas traités à nouveau. Si vous avez eu uneREDIRECT_MAJOR
aprèsdocroot/.htaccess
a été traité (par exemple, si vous omettez leL
drapeau de la premièreRewriteRule
), vous aurez toujours de l'avoir, mais ces directives ne fonctionne pas à nouveau la valeur de votre choix de nom de variable.Héritage
Donc, disons que vous voulez:
définir des variables d'environnement dans
RewriteRule
directives à un niveau de l'arborescence du répertoire (commedocroot/.htaccess
)elles seront disponibles dans les scripts à des niveaux plus profonds
les mettre à disposition à l'attribution des noms de domaine
être en mesure d'avoir de réécriture des directives, en plus profondément imbriqués
.htaccess
fichiersUne solution possible est d'utiliser
RewriteOptions inherit
directives dans le plus profondément imbriqués.htaccess
fichiers. Qui vous permet de re-exécuter la réécriture des directives en moins profondément imbriqués les fichiers et utiliser les techniques décrites ci-dessus pour définir les variables avec les noms choisis. Toutefois, notez que cela augmente la complexité, car vous devez être plus prudent de l'élaboration de la réécriture des directives dans le moins profondément imbriqués les fichiers de sorte qu'ils ne causent pas de problèmes lors de l'exécution à nouveau à partir de la plus profondément répertoires imbriqués. Je crois Apache bandes de la per-dir préfixe pour le plus profondément imbriqués répertoire et exécute la réécriture de directives dans le moins profondément imbriqués les fichiers sur cette valeur.@truelle de la technique de
Aussi loin que je peux voir, le soutien pour l'utilisation d'une construction comme
%{ENV:REDIRECT_VAR}
dans la valeur de la composante d'unRewriteRule
E
drapeau (par exemple[E=VAR:%{ENV:REDIRECT_VAR}]
) ne semble pas être documenté:Il ne semble pas fonctionner, mais si vous voulez éviter de compter sur quelque chose de sans-papiers (corrigez-moi si je me trompe à ce sujet), il peut facilement être fait de cette façon au lieu de cela:
SetEnvIf
Je ne recommande pas se fier sur ce point, car il ne semble pas être compatible avec la comportement documenté (voir ci-dessous), mais ce (en
docroot/.htaccess
, avec Apache 2.2.20) fonctionne pour moi:Pourquoi?
Je ne sais pas ce que la justification de la préfixation de ces noms avec
REDIRECT_
est -- pas surprenant, car il ne semble pas être mentionné dans la documentation d'Apache sections pour les directives de mod_rewrite,RewriteRule
drapeaux, ou les variables d'environnement.Au moment où il semble comme une nuisance importante pour moi, en l'absence d'une explication de pourquoi c'est mieux que de laisser l'attribution des noms de domaine seul. Le manque de documentation contribue à mon scepticisme à ce sujet.
Être en mesure de définir des variables d'environnement dans les règles de réécriture est utile, ou au moins, il serait. Mais l'utilité est fortement diminuée par ce nom de changement de comportement. La complexité de ce post illustre comment les noix de ce comportement et les cerceaux qui doivent être sauté à travers pour essayer de surmonter sont.
RewriteRule ^A\.php sub/B.php [L]
et puisRewriteRule .* - [E=MAJOR:flaw]
, si la première règle s'applique,MAJOR
de ne pas être mis en cause le premier règle des matchs et de la dernière (L'indicateur). L'URL est réécrite et apache ré-itère sur lamod_rewrite
s'intérieur de la boucle et ce temps correspond àRewriteRule .* - [E=MAJOR:flaw]
, définit la variable d'environnement, et seulement alors, il va après le prochain.htaccess
à l'intérieur de/sub
. Est-il correct?RewriteRule
réécrit l'URL desub/B.php
et puis c'est game over pourdocroot/.htaccess
: la variable env jamais fait ensemble. (Décrire que comme l'env variable "disparaître" peut-être pas le meilleur moyen de le mettre.) Encore une fois, c'est si il y a unsub/.htaccess
qui contient de la réécriture directive connexe.: **If the URI changed L will re-inject into the the next round (the outer loop)** So I guess that if a URL is rewritten with [L] flag set, mod_rewrite will pass to the next round, but this time taking into consideration the most inner
.htaccess` fichier à l'intérieur de la version remaniée du chemin (dans ce cassub/.htaccess
). Au moins, c'est ce que je comprends de votre réponse, et la réponse que j'ai lié.modules/http/http_request.c
qui s'exécuterename_original_env()
a été ajoutée à l'importation en vrac de 1.3.x CVS, et je n'arrive pas à trouver que l'histoire précédente n'importe où maintenant. Vous devez déposer un rapport de bug pour avoir leur expliquer et de justifier plus clairement.Je n'ai pas testé ce à tous et je sais qu'il ne faut pas aborder les points A ou B, mais il y a une description de cette question dans les commentaires de documentation de PHP et des solutions possibles pour accéder à ces variables à l'aide de
$_SERVER['VAR']
:http://www.php.net/manual/en/reserved.variables.php#79811
MODIFIER - certains plus de réponses à la question offert:
Un: Les variables d'environnement sont renommés par Apache s'ils sont impliqués dans une redirection. Par exemple, si vous avez la règle suivante:
Ensuite, vous pouvez accéder à VAR1 et VAR2 à l'aide de
$_SERVER['VAR1']
et$_SERVER['VAR2']
. Toutefois, si vous rediriger la page comme ceci:Ensuite, vous devez utiliser
$_SERVER['REDIRECT_VAR1']
, etc.B: La meilleure façon de surmonter ce problème est de traiter les variables qui vous intéressent à l'aide de PHP. Créer une fonction qui s'exécute par le biais de la
$_SERVER
tableau et trouve les objets dont vous avez besoin. Vous pouvez même utiliser une fonction comme ceci:Que je ne veux pas modifier mon code (je ne peux pas modifier le code de la bibliothèques utilisées), je suis allé avec l'approche suivante: alors que l'amorçage de mon application – par exemple, dans mon
index.php
– je reprends les$_ENV
superglobale de sorte que les variables préfixées avecREDIRECT_
sont réécrits à la normale nom:Non seulement nous définir directement dans
$_ENV
, mais nous avons aussi le stocker à l'aide deputenv()
. De cette façon, le code existant et des bibliothèques – qui sont susceptibles d'utilisergetenv()
– peut fonctionner correctement.Sur une note: si vous êtes extraire les en-têtes comme
HTTP_AUTHORIZATION
– dans votre code, vous avez besoin de faire le même genre de manipulation sur$_SERVER
: