【问题标题】:REQUEST_URI is not overridden by using APACHE RewriteRule?使用 APACHE RewriteRule 不会覆盖 REQUEST_URI?
【发布时间】:2011-08-17 09:55:39
【问题描述】:

问题:

我正在使用 Kohana/PHP 为其他公司开发托管网站。 我让客户在他们的 DNS 服务器中输入一个 CNAME 条目以指向我的域。例如。 http://invites.somecompany.com 指向http://www.mydomain.com

因此,我的 apache 服务器上的 %{HTTP_HOST} 条目是 'invites.somecompany.com'

我想把http://invites.somecompany.com/invite改写成http://www.mydomain.com/invites/invite

尽管 Apache 似乎正在这样做,但 $_SERVER['REQUEST_URI'] 仍然是“/”。 问题是 Kohana 使用 $_SERVER['REQUEST_URI'] 将请求路由到适当的控制器代码。在这种情况下,它将它路由到 base 索引控制器,而不是 'invites' 控制器。

事实:

我正在使用的 Apache mod_rewrite 指令(在 .htaccess 文件中):-

RewriteCond %{HTTP_HOST} !^www.mydomain.com$
RewriteCond %{REQUEST_URI} !.*invites.*
RewriteRule ^(.*)$ invites/$1

# For Kohana
RewriteRule .* index.php?kohana_uri=$0 [PT,QSA,L]

在 index.php 中,我这样做了:

var_dump($_SERVER);

我明白了:

'REQUEST_URI' => string '/',
'QUERY_STRING' => string 'kohana_uri=invites/index.php&kohana_uri=invites/invite'
'REDIRECT_QUERY_STRING' => string 'kohana_uri=invites/invite'

所以 mod_rewrite 不会修改 REQUEST_URI ?

需要:

'REQUEST_URI' => 'invites/invite',
'QUERY_STRING' => string 'kohana_uri=invites/invite',

我如何得到它?

======================= 编辑

重写日志条目:-

strip per-dir prefix: /Users/project/invite -> invite
 applying pattern '^(?:application|modules|system)\b.*' to uri 'invite'
 strip per-dir prefix: /Users/project/invite -> invite
 applying pattern '\.git' to uri 'invite'
 strip per-dir prefix: /Users/project/invite -> invite
 applying pattern '^(.*)$' to uri 'invite'
 rewrite invite -> invites/invite
 add per-dir prefix: invites/invite -> /Users/project/invites/invite
 strip per-dir prefix: /Users/project/invites/invite -> invites/invite
 applying pattern '.*' to uri 'invites/invite'
 rewrite invites/invite -> index.php?kohana_uri=invites/invite
 add per-dir prefix: index.php -> /Users/project/index.php
 strip document_root prefix: /Users/project/index.php -> /index.php
 internal redirect with /index.php [INTERNAL REDIRECT]
 strip per-dir prefix: /Users/project/index.php -> index.php
 applying pattern '^(?:application|modules|system)\b.*' to uri 'index.php'
 strip per-dir prefix: /Users/project/index.php -> index.php
 applying pattern '\.git' to uri 'index.php'
 strip per-dir prefix: /Users/project/index.php -> index.php
 applying pattern '^(.*)$' to uri 'index.php'
 rewrite index.php -> invites/index.php
 add per-dir prefix: invites/index.php -> /Users/project/invites/index.php
 strip per-dir prefix: /Users/project/invites/index.php -> invites/index.php
 applying pattern '.*' to uri 'invites/index.php'
 rewrite invites/index.php -> index.php?kohana_uri=invites/index.php
 add per-dir prefix: index.php -> /Users/project/index.php
 initial URL equal rewritten URL: /Users/project/index.php [IGNORING REWRITE]

【问题讨论】:

  • 这就是 mod_rewrite 的工作原理。

标签: php apache mod-rewrite dns kohana


【解决方案1】:

1.) 如果您手动调用此链接,它是否有效? http://www.mydomain.com/invites/invite

2.) RewriteCond %{HTTP_HOST} !^www.mydomain.com$需要像RewriteCond %{HTTP_HOST} !^www\.mydomain\.com$一样被转义

3.) RewriteRule .* index.php?kohana_uri=$0 [PT,QSA,L] 是一个无限循环,因为 index.php 也适合正则表达式 .*

4.) 您需要 R 标志将用户重定向到邀请/RewriteRule ^(.*)$ invites/$1 [R=301]%{REQUEST_URI} 与浏览器地址栏中的 uri 相同。

5.) 如果您不想重定向访问者,您可以“破解”kohana 系统并在 index.php 的第一行设置$_SERVER['REQUEST_URI'] = $_GET['myURI'];,如果这是让它运行的唯一选项。 myURI 可以通过 mod_rewrite 随意填写。

【讨论】:

  • 谢谢@mgutt。 5)是我最终做的。
  • 我学到的另一个有趣的花絮:如果你在 .htaccess 文件中有重写规则,它们会运行两次。另一种方法是将重写规则插入到 httpd.conf 文件中,但是我不断收到“400 bad request”错误。
【解决方案2】:

由于 mod_rewrite 的工作方式,您不能立即将它放在 $_SERVER['REQUEST_URI'] 中。如果您乐于修改$_SERVER(这有时被认为是个坏主意),可以这样:

$_SERVER['REQUEST_URI'] = $_GET['kohana_uri'];
$_SERVER['QUERY_STRING'] = $_SERVER['REDIRECT_QUERY_STRING'];

【讨论】:

    【解决方案3】:

    删除了我之前的答案,因为它完全错误。感谢提供文档链接,学到了一些新东西。

    删除 QSA 标志:

    # For Kohana
    RewriteRule .* index.php?kohana_uri=$0 [PT,L]
    

    Per the Docs:

    'qsappend|QSA'(查询字符串追加) 此标志强制重写引擎 追加查询字符串的一部分 替换字符串到现有的 字符串,而不是替换它。采用 当您想向其中添加更多数据时 通过重写规则查询字符串。

    第一次就应该注意到了。

    【讨论】:

    • 不是真的。 check httpd.apache.org/docs/1.3/mod/mod_rewrite.html#RewriteRule "反向引用是 $N (N=0..9) 标识符,将被匹配模式的第 N 组的内容替换。"
    • 我不会与文档争论,但我从未见过使用 $0。此外,您正在按照我在您之前的规则中所说的去做。为什么不一致?
    • 我以前用过 $0 并且可以正常工作(与 preg_match 中的相同)。不一致是我的错,但即使我使它一致(通过使用 $0 始终),结果仍然是一样的。
    • 有趣。有什么理由使用 $0 vs $1 作为起点?只是个人喜好吗?
    • 我看到 $0 在其他地方被使用,所以你可以说它是一种偏好。
    猜你喜欢
    • 1970-01-01
    • 2013-01-16
    • 2015-04-28
    • 1970-01-01
    • 1970-01-01
    • 2021-12-08
    • 1970-01-01
    • 1970-01-01
    • 2014-06-25
    相关资源
    最近更新 更多