![在 fcgi 看到请求之前使 mod_rewrite 规则进程](https://linux22.com/image/615898/%E5%9C%A8%20fcgi%20%E7%9C%8B%E5%88%B0%E8%AF%B7%E6%B1%82%E4%B9%8B%E5%89%8D%E4%BD%BF%20mod_rewrite%20%E8%A7%84%E5%88%99%E8%BF%9B%E7%A8%8B.png)
有没有办法让我.htaccess
文件中的 mod_rewrite 规则在 fcgi 后面的 PHP 看到请求之前生效?
我有一个电子邮件验证链接,我想在 PHP 在数据库中将其标记为已确认之前将其从根目录重定向到登录页面。
这些是我在我的 中的规则.htaccess
,它们起作用,但是 PHP 在重写规则生效之前看到了请求。
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{QUERY_STRING} activation_key=
RewriteRule ^$ /login [R,L]
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
当 PHP 看到包含查询字符串的请求时activation_key
,它会将用户标记为已激活。如果用户已激活,页面将显示“未知验证链接”错误。
通过这些重写规则,请求会重定向到页面/login
并显示错误,这表明 - 我认为 - PHP 已经看到了该请求。
这是 mod_fastcgi 配置:
<IfModule mod_fastcgi.c>
DirectoryIndex index.html index.shtml index.cgi index.php
AddHandler php5-fcgi .php
Action php5-fcgi /php5-fcgi
Alias /php5-fcgi /usr/lib/cgi-bin/php5-fcgi
FastCgiExternalServer /usr/lib/cgi-bin/php5-fcgi -host 127.0.0.1:9000 -pass-header Authorization
</IfModule>
答案1
如果我理解正确的话:
- 您向 发出请求
/?activation_key=foobar
,Apache 返回响应以将您重定向到/login
。 - 您向 发出后续请求
/login
,该页面显示它已经看到了验证链接。但此请求中没有activation_key
,它只存在于第一个请求中。它可能之前已经看到过空字符串,这就是它现在抛出错误的原因。(您的 PHP 脚本中的确切逻辑可能与此解释不符,但我怀疑它是类似的。)
尝试像这样更改重写规则:
RewriteCond %{QUERY_STRING} activation_key=[^&]*
RewriteRule ^$ /login?activation_key=%1 [R,L]
它将捕获激活密钥并在下次请求时将其传递,/login
以便 PHP 获得该密钥。
在调试时回显或记录查询字符串或整个请求甚至整个$_SERVER
超级全局变量到文件可能是值得的。
您的上一条重写规则/
中有一个多余的内容,但其实并不需要。以下规则会更好:
RewriteRule ^ index.php [L]
.htaccess
文件和相关AllowOverride all
指令会带来性能损失。在使用strace
和观察所有文件操作以寻找.htaccess
文件可能隐藏的所有位置时,这一点变得非常明显。如果您运行的是自己的 Apache 服务器而不是共享主机,那么您可能还想将这些规则放入主配置中并设置AllowOverride
为 none。在<Directory>
块内,它们将按原样工作。在其他地方,它们将需要一个额外的前导斜杠。