在 Apache RewriteRule 指令中设置环境变量时,是什么导致变量名称带有“REDIRECT_”前缀?

2023-12-13

我正在尝试使用以下命令设置 Apache 环境变量(用于 PHP)[E=VAR:VAL].htaccess 文件中 RewriteRule 规则的标记。

我已经发现变量在 PHP 中作为服务器变量进行访问$_SERVER而不是$_ENV(这有一定的道理)。但是,我的问题是对于某些规则[E=VAR:VAL]标志按预期工作,我最终得到一个变量$_SERVER['VAR']但对于其他规则我以变量结尾$_SERVER['REDIRECT_VAR'] or $_SERVER['REDIRECT_REDIRECT_VAR'], etc

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 每个目录上下文

这似乎发生在.htaccess每个目录(per-dir)上下文:

假设 Apache 处理.htaccess包含重写指令的文件。

  1. Apache 使用所有标准 CGI / Apache 变量填充其环境变量映射

  2. 重写开始

  3. 环境变量设置在RewriteRule指令

  4. 当 Apache 停止处理RewriteRule指令(因为L标志或规则集末尾)并且 URL 已被更改RewriteRule,Apache 重新启动请求处理。

    如果您不熟悉这部分,请参阅L标记文档:

    thus the ruleset may be run again from the start. Most commonly this will happen if one of the rules causes a redirect - either internal or external - causing the request process to start over.
  5. 据我观察,我相信当#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,因此在两者之后RewriteRules 被处理后,Apache 重新启动该过程并处理.htaccess再次。第二次,第一次RewriteRule被跳过是因为RewriteCond指令,但第二个RewriteRule匹配,设置环境变量(再次),并且,重要的是,不更改 URL。因此请求/重写过程不会重新开始,并且我选择的变量名称会保留。在这种情况下,我实际上两者都有REDIRECT_EFFECTIVE_DOCUMENT_ROOT and 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

And a docroot/.htaccess像这样:

RewriteRule ^A\.php sub/B.php [L]

RewriteRule .* - [E=MAJOR:flaw]

所以你要求/A.php,并且它被重写为sub/B.php。你还有你的MAJOR多变的。

但是,如果您有任何重写指令docroot/sub/.htaccess(即使只是RewriteEngine Off or RewriteEngine On), your MAJOR变量消失。这是因为一旦 URL 被重写为sub/B.php, docroot/sub/.htaccess被处理,如果它包含任何重写指令,则重写指令docroot/.htaccess不会再次被处理。如果你有一个REDIRECT_MAJOR after docroot/.htaccess已处理(例如,如果您省略L从一开始的标志RewriteRule),您仍然会拥有它,但这些指令不会再次运行来设置您选择的变量名称。

遗产

那么,假设您想要:

  1. 设置环境变量RewriteRule目录树特定级别的指令(例如docroot/.htaccess)

  2. 让它们在更深层次的脚本中可用

  3. 让它们具有指定的名称

  4. 能够更深层地嵌套重写指令.htaccess files

一个可能的解决方案是使用RewriteOptions inherit更深层嵌套的指令.htaccess文件。这允许您在嵌套深度较低的文件中重新运行重写指令,并使用上面概述的技术来设置具有所选名称的变量。但是,请注意,这会增加复杂性,因为您必须更加小心地在嵌套较浅的文件中编写重写指令,以便它们在从嵌套较深的目录再次运行时不会导致问题。我相信 Apache 会去除嵌套较深的目录的 per-dir 前缀,并在嵌套较浅的文件中根据该值运行重写指令。

@trowel的技术

据我所知,支持使用像%{ENV:REDIRECT_VAR}在 a 的值分量中RewriteRule E标志(例如[E=VAR:%{ENV:REDIRECT_VAR}])似乎不是记录在案:

VAL 可能包含将被扩展的反向引用($N 或 %N)。

它似乎确实有效,但如果您想避免依赖未记录的内容(如果我错了,请纠正我),可以轻松地通过以下方式完成:

RewriteCond %{ENV:REDIRECT_VAR} (.+)
RewriteRule .* - [E=VAR:%1]

SetEnvIf

我不建议依赖这个,因为它似乎与记录的行为(见下文),但是这个(在docroot/.htaccess,使用 Apache 2.2.20)对我有用:

SetEnvIf REDIRECT_VAR (.+) VAR=$1

只有那些由早期 SetEnvIf[NoCase] 指令定义的环境变量才可用于以这种方式进行测试。

Why?

我不知道给这些名字加上前缀的理由是什么REDIRECT_是——并不奇怪,因为 Apache 文档部分中似乎没有提到它mod_rewrite 指令, RewriteRule flags, or 环境变量.

目前,这对我来说似乎是一个很大的麻烦,因为没有解释为什么它比保留分配的名称更好。缺乏文档只会加剧我对此的怀疑。

能够在重写规则中分配环境变量是有用的,或者至少是有用的。但这种改名行为大大削弱了实用性。这篇文章的复杂性说明了这种行为是多么疯狂,以及为了克服它而必须克服的困难。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 Apache RewriteRule 指令中设置环境变量时,是什么导致变量名称带有“REDIRECT_”前缀? 的相关文章

  • PHP CLI 有几秒钟的延迟

    当我在 CLI 模式下运行 PHP 时 CentOS 6 5 下的 PHP 5 6 6 使用 VirtualBox 作为虚拟机运行 即使我只检查版本并且禁用 php ini 文件 也会有几秒钟的延迟 time php n v PHP 5 6
  • 无限滚动启用(wordpress)

    因此 我发现本教程可以启用无限滚动 http wptheming com 2012 03 infinite scroll to wordpress theme http wptheming com 2012 03 infinite scro
  • PHP静态函数

    我有一个关于 php 中的静态函数的问题 假设我有一堂课 class test public function sayHi echo hi if I do test sayHi 它工作没有问题 class test public stati
  • 当用户单击链接时如何在表中创建新字段

    我的表格如下图所示 In order to insert data from this form into table I coded this supplier info supplier name POST supplier name
  • WordPress 中的随机永久链接键

    我想为 WordPress 中的每个新帖子都有一个自定义永久链接 例如 http mysite com x5Kvy6 http mysite com x5Kvy6 如 bit ly 我尝试了这个小脚本 但它只在永久链接的帖子标题中添加了 5
  • 如何在会话过期后自动更新数据库而不刷新我的页面

    您需要刷新或单击该代码 然后它才会转到索引页面 并且在会话过期后更新数据库之前 如何让会话过期后自动更新数据库 使用户活跃度为0 而无需刷新或点击页面 idletime 3600 after 1hr the user gets logged
  • 在 Symfony2 (Doctrine) 和 MySQL 中启用微秒

    我有一个具有一列 日期时间 类型的实体来存储时间戳 ORM Column type datetime protected timestamp 我有 MySQL 5 5 40 我发现它不存储微秒 所以我切换到 5 6 21 并导入了所有表格和
  • Monolog - 仅记录特定级别的错误

    我在普通 PHP 应用程序中使用 Monolog 我只想记录特定级别的错误 INFO 和不高于 因为我还有其他处理程序 这是我的代码
  • 根据子域 htaccess 显示其他文件夹的内容

    当我请求时 subdomain1 domain com i want to show the contents of httpdocs subdomain1 当我请求时 subdomain2 domain com i want to sho
  • date() 和 strtotime 的问题

    这是我所拥有的 str 12 25 2009 echo date Y m d strtotime str 这会产生 1969 12 31 而不是 2009 12 25 如果我将 str var 设置为 01 01 2009 我将得到正确的
  • PHPExcel - 如何使用 preg_replace 替换文本

    我正在使用 PHPExcel 将数据库中的数据提取到组织好的 Excel 工作表中 除了一件事之外 一切都运转良好 我的数据库条目有时可能包含 HTML 标记 例如 strong strong br p p 等等 所以我设法让这个 PHP
  • 数据库记录的多级菜单

    我需要一些有关 PHP 的帮助 我有一个工作正常的多级 css 菜单 但现在我想根据数据库中的记录生成 菜单代码 div ul class dropdown li a href Link 1 a li li a href Link 2 a
  • simplexml_load_string 函数出现巨大的输入查找错误

    我有一个大小不同的 API 响应 当我尝试使用将 xml 对象转换为 std 对象时 它不会在大型 xml 数据 约 20MB 上显示错误 这是我的代码 xml simplexml load string apiResponse objec
  • 在 foreach 循环中使用 next

    我正在使用 foreach 循环数组 在特定情况下 我需要在迭代到达下一个元素 如预测 之前知道下一个元素的值 为此 我计划使用该功能next http www php net manual en function next php 在文档
  • 将数组值翻转为数组键的函数? [复制]

    这个问题在这里已经有答案了 有没有一个php函数可以接受下面的数组 array size 4 1 gt string 0 6 gt string 1 7 gt string 1 8 gt string 7 将其翻转到下面的数组 请注意 数组
  • Laravel 4 类如何检测它是在 Artisan 任务中运行还是在浏览器请求中运行?

    我有一些应用程序启动代码 需要知道它当前是在 artisan 任务中运行还是在浏览器请求中调用 我如何在 Laravel 4 中检测到这一点 这是最好的方法 if App runningInConsole echo Running in a
  • Outlook 2007 接收 html 邮件作为带有标头的源,其他 MUA 工作正常。为什么?

    我有几个简单的表单 可以发送纯 html 电子邮件 大多数客户端 Gmail Lotus Notes 8 hotmail live windows live mail outlookexpress 都能正常接收电子邮件 但 Outlook
  • PHP:系统时区设置错误

    我尝试在 MAMP 下的终端中使用 PHP 但出现与系统时区设置相关的错误 我该如何修复这个错误 应用程序 MAMP bin php5 bin php 回声 php PHP 严格标准 PHP 启动 它 依赖系统是不安全的 时区设置 请使用
  • 是否可以倒回 PDO 结果?

    我正在尝试为 PDO 语句的结果编写一个迭代器 但找不到任何回退到第一行的方法 我想避免调用 fetchAll 和存储所有结果数据的开销 first loop works fine foreach statement as result d
  • PHP SFTP 简单文件上传

    我正在使用 phpseclib SFTP 类 并尝试上传这样的文件 sftp new Net SFTP mydomain com if sftp gt login user password exit Login Failed sftp g

随机推荐

  • 我如何覆盖核心 Symfony2 类?

    我想重写核心 Symfony2 类 具体来说 我想覆盖供应商 symfony symfony src Symfony Bundle FrameworkBundle Template TemplateReference php Templat
  • 如何在Boost Spirit解析器中打印符号表匹配的变量?

    我是使用初学者boost spirit 假设我有以下代码来解析带有变量的简单算术表达式 include
  • 使用 sed 插入换行符 (\n)

    我正在尝试将一些列表清理到格式正确的 CSV 文件中以进行数据库导入 我的起始文件看起来像这样 每个 行 应该跨越多行 如下所示 Mr John Doe Exclusively Stuff 186 Caravelle Drive Ponte
  • context.filter 在 safari 上不起作用

    我正在使用 React 和 Safari 构建一个绘图应用程序 context filter无法正常工作 下面是在 chrome 和 firefox 上渲染的图片以及在 safari 上渲染的图片 对于 Safari 来说还有其他选择吗 S
  • 使用PCA选择特征

    我正在做无监督分类 为此 我有 8 个特征 绿色方差 绿色标准差 红色平均值 红色方差 红色标准差 色调平均值 色调方差 色调标准差 用于分类每个图像 我想使用 PCA 选择 3 个最重要的特征 我编写了以下代码用于特征选择 其中特征尺寸为
  • Google Fonts 字体无法加载

    我正在尝试将 PT Sans 添加到时事通讯中 但由于某种原因它没有加载我已经复制了几乎所有代码 但它不起作用 我将非常感谢任何可以提供帮助的人 这是 CSS 代码 h1 h2 h3 font family PT Sans sans ser
  • 可执行目标文件和虚拟内存

    我是 Linux 和虚拟内存的初学者 仍在努力理解虚拟内存和可执行对象文件之间的关系 假设我们有一个可执行目标文件a out存储在硬盘驱动器磁盘上 假设最初 a out 有一个 data具有值为 2018 的全局变量的部分 当加载程序运行时
  • JavaScript:通过 ID 设置嵌套对象值

    我想知道在 JavaScript 中更新多级对象集合成员的最佳方法是什么 这是我的收藏的简化版本 this Steps id 1 text test childSteps id 2 text test id 3 text test id 4
  • Bundle 正在等待名称空间处理程序 [http://camel.apache.org/schema/blueprint]

    我编写了一个简单的 apache Camel 项目 最终将部署在 FUSE 容器中 现在 我只是想让基本的单元测试正常工作 我正在使用这个例子here作为起点 我已经编写了有效的单元测试 但是当我包含蓝图文件时 我在测试输出中得到以下条目
  • 子类 Python 列表以验证新项目

    我想要一个 python 列表 它在外部将自身表示为其内部列表项的平均值 但在其他方面则表现为列表 它应该提高一个TypeError如果添加的项目无法转换为浮点数 我坚持的部分是提高TypeError 对于通过任何列表方法添加的无效项目 应
  • 可变寿命

    当执行行超出代码块时变量会发生什么 例如 1 public void myMethod 2 3 int number 4 number 5 5 所以 我们声明并设置变量 当它超出代码块 第 5 行 时 变量 number 发生了什么 这是创
  • 如何获得完全限定的程序集名称

    有没有简单的方法可以获得程序集的完全限定名称 例如 section type section 这是无耻的复制粘贴我记下来这是获取项目输出的 FQAN 的简单方法 Open Visual Studio Go to Tools gt Exter
  • UILocalNotification 可以用来唤醒后台任务吗

    我想知道 是否有可能以某种方式 唤醒 后台的任务 以快速检查网络上的某些内容 我认为这可以通过 UILocalNotification 来完成 但是 无论我尝试什么 当应用程序在后台时 我无法让 didReceiveLocalNotific
  • 在 FragmentActivity 中创建自定义选项卡

    我正在尝试在 android 中创建自定义选项卡 我已将选项卡创建为FragmentActivity and FragmentPagerAdapter 这是代码 但我真的不知道在哪里使用自定义选项卡 View tabIndicator La
  • 在接口中的静态方法上调用静态

    反汇编一些 Java 8 代码我发现一些invokestatic调用接口中的静态方法 特别是这是java util function Function identity 在 const 池中使用 InterfaceMethodRef 这是什
  • 来自/到 Firebase 数据库服务器的流量是否被压缩?

    也许是一个有点愚蠢的问题 但是 来自 到 firebase DB 服务器的流量是多少 压缩的 如果是这样 什么算法 对于 Firebase 客户端发送 接收的纯文本数据 通常会出现什么压缩率 压缩对当今设备上的 CPU 使用率是否有明显影响
  • 如何在 Laravel 9 中使用foreignUuid

    所以我尝试在表中使用 UUID 而不是 id 我有两个表 在两个表中 我都使用 UUID 来生成 id 之后 我尝试在第二个表中使用一个 id 作为外来 ID 我使用 Laravel 9 这是我的第一张桌子 这是我的第二张桌子 但当我试图跑
  • 在 API 调用 (R) 中使用 httr::RETRY() 函数实现调用重试

    我用带有 R 的联合国商品贸易统计数据库 UN Comtrade 数据 API library rjson get Comtrade lt function url http comtrade un org api get maxrec 5
  • 如果 mongodb 聚合不使用 $lookup 索引,为什么使用索引时性能会提高?

    我有以下代码片段来运行聚合命令 console time something const cursor await db collection main aggregate match mainField mainField lookup
  • 在 Apache RewriteRule 指令中设置环境变量时,是什么导致变量名称带有“REDIRECT_”前缀?

    我正在尝试使用以下命令设置 Apache 环境变量 用于 PHP E VAR VAL htaccess 文件中 RewriteRule 规则的标记 我已经发现变量在 PHP 中作为服务器变量进行访问 SERVER而不是 ENV 这有一定的道