我有一个名为otp.php
的PHP文件。
URL栏中的URL为
http://localhost/college/otp/MTA=/teacher
应将其视为
http://localhost/college/otp.php?user=MTA=&role=teacher
为此,我在 http://localhost/college/ 中创建了.htaccess
文件:
RewriteEngine On # Turn on the rewriting engine
RewriteRule ^otp/?$ otp.php [NC,L]
RewriteRule ^otp/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2 [NC,L]
但是,otp.php
文件说:
注意:未定义的索引:在C:\ wamp \ www \ college \ otp.php中的角色 11
注意:未定义索引:在线的C:\ wamp \ www \ college \ otp.php中的用户 11
URL栏中的URL为
http://localhost/college/otp/MTA/teacher
应视为
http://localhost/college/otp.php?user=MTA&role=teacher
如何解决此问题?
答案 0 :(得分:2)
URL: /college/otp/MTA=/teacher
Target: /college/otp.php?user=MTA=&role=teacher
.htaccess: /college/.htaccess
RewriteRule ^otp/[A-Za-z-]+/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2 [NC,L]
您的RewriteRule
模式需要稍作修改以匹配示例URL,因为它目前在=
中的MTA=
上失败。 (尽管我刚刚注意到,对您问题的“更新”没有在URL中显示=
?)还需要 capture 捕获此模式,以使{{1 }}捡起来。
因此,以上指令应显示为:
$1
这假定 RewriteRule ^otp/([A-Za-z-]+=)/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2 [NC,L]
总是出现在路径段的末尾,如您最初的示例所示(如果可以出现在任何地方,请将其包括在字符类中,尽管这可能是一个有点混乱)。可能不需要=
标志,除非您还需要允许使用NC
的混合大小写版本(不可取)。您已经在正则表达式中允许混合大小写。
UPDATE#1::似乎第二个路径段是base64编码的字符串/整数。为此,您将需要在正则表达式中包含数字,并且可能有0、1或2个尾随otp
字符。也不需要匹配连字符。例如:
=
但是,您似乎正在遇到的另一个问题(实际上是您正在“看到”的问题)是与MultiViews(mod_negotiation的一部分)发生冲突。为了使上面的mod_rewrite指令起作用(实际上,可以执行任何操作),需要禁用此功能。如果您没有在 RewriteRule ^otp/([A-Za-z0-9]+={0,2})/([A-Za-z0-9-]+)/?$ otp.php?user=$1&role=$2 [NC,L]
中启用此功能,请通过在.htaccess
文件顶部添加以下内容来禁用它:
.htaccess
如果启用了MultiViews,则当您请求Options -MultiViews
(存在具有相同 basename 的文件时,该文件也将返回适当的mime类型)mod_negotiation发出{{ 1}}。这里的问题是发生在之前 mod_rewrite,因此otp
最终在没有任何URL参数的情况下被调用。
旁边:
您的代码不应生成这些“未定义索引”通知。由于这实际上是“用户提供的数据”,因此您应该在脚本中进行检查。例如:
otp.php
otp.php
请注意,Apache不支持行尾注释,因此您应该从第一行中删除$role = isset($_GET['role']) ? $_GET['role'] : null;
文本。 (但是,行尾注释似乎“有效”,这与Apache指令的一般工作方式只是巧合,否则它们将导致500个内部服务器错误。)
UPDATE#2:
如果URL栏上有
RewriteEngine On # Turn on the rewriting engine
,可以将其更改为# Turn on the rewriting engine
吗?
是的,可以这样做。尽管我假设http://localhost/college/otp.php?user=MTA=&role=teacher
应该出现在两个地方? (您在源中有http://localhost/college/otp/MTA/teacher
,在目标中有MTA=
,这大概会破坏base64编码吗?)我假设您已经在内部链接到正确的URL,这仅是为了避免流浪请求(搜索引擎,反向链接等?)
您可以在上述重写之前实施外部重定向,请注意不要重定向已重写的URL并触发重定向循环。例如:
MTA=
这基本上是与内部重写(在MTA
文件中稍后出现)相反的。根据{{1}}环境变量进行检查的条件确保了它仅触发直接请求,而不触发重写请求。
请注意,由于这是外部重定向,因此您需要在 substitution 参数中包含相对于根的URL路径。即。包括RewriteCond %{ENV:REDIRECT_STATUS} ^$
RewriteCond %{QUERY_STRING} ^user=([A-Za-z0-9]+={0,2})&role=([A-Za-z0-9-]+)
RewriteRule ^(otp)\.php$ /college/$1/%1/%2 [QSD,R=302,L]
子目录。 (或者,您可以使用相对的替代并设置.htaccess
-尽管只有在具有多个这些指令的情况下才这样做。)
REDIRECT_STATUS
是对/college
模式的反向引用(即始终为RewriteBase
),而$1
和RewriteRule
是反向引用到之前的 CondPattern ,即分别是otp
和%1
URL参数的值。
%2
标志(Apache 2.4+)从请求中丢弃原始查询字符串。
答案 1 :(得分:0)
This tool可以帮助您为RewriteRules编写正确的表达式。也许,这种表达会给您一个想法,问题可能出在哪里:
(.*otp)\/([A-Za-z0-9-]+=)\/([A-Za-z0-9-]+)
此link帮助您可视化RewriteRule的表达式:
然后,您可以编写一个RewriteRule,也许类似于:
<IfModule mod_rewrite.c>
RewriteEngine On # Turn on the rewriting engine
RewriteCond %{HTTP_HOST} localhost [NC]
RewriteRule (.*otp)\/([A-Za-z0-9-]+=)\/([A-Za-z0-9-]+) $1.php?user=$2&role=$3 [NC,L]
</IfModule>
每次修改.htaccess
文件时,您可能希望清除浏览器历史记录。