URL重写如何影响PHP的$_GET
参数?
说我有http://example.com/index.php?p=contact
这样的网址,我使用$_GET['p']
告诉index.php
提供联系页面。如果我使用将网址转换为http://example.com/contact
的重写规则,$_GET['p']
仍会按预期工作吗?
如果确实如此,你能详细说明它的工作原理吗?如果没有,可以使用什么策略来解决问题,以便页面在重写和不重写时都能正常工作?
答案 0 :(得分:32)
我会修改格兰特的回答“是的,这将大部分正常工作。”
具体而言,mod_rewrite
关于现有查询字符串的行为可能会令人惊讶。例如,让我们采用以下规则来转换您提供的URL:
RewriteRule /contact /index.php?p=contact
这会正确地将/contact
重写为/index.php?p=contact
,并且可以通过$_GET['p']
访问页面名称。但是,如果将此技术用于使用页面名称以外的参数的脚本,则会稍微复杂一些。此规则还会将/contact?person=Joe
翻译为/index.php?p=contact
。 person=Joe
参数完全消失!有两种方法可以解决这个问题。
最简单的方法是在规则上使用[QSA]
(“查询字符串追加”)标记,这将把原始查询字符串放在规则中提供的参数之后,进行翻译/contact?person=Joe
到/index.php?p=contact&person=Joe
:
RewriteRule /contact /index.php?p=contact [QSA]
但是,这样可以覆盖您的p=
参数。访问/contact?p=about
将被重写为/index.php?p=contact&p=about
,因此$_GET['p']
将在您的脚本中返回“about”,而非“联系”。要解决此问题,请改用QUERY_STRING
变量:
RewriteRule /contact /index.php?%{QUERY_STRING}&p=contact
这可以保证$_GET['p']
在使用此规则时始终返回“联系”,无论您的访问者是否在弄乱您的网址。 : - )
答案 1 :(得分:4)
是的,这将按预期工作。
答案 2 :(得分:1)
重写URL时,这是由mod_rewrite完成的 - 最后检索的页面仍然是“旧”页面,即index.php?p = contact。换句话说,浏览器检索/联系。 mod_rewrite然后将其重写为index.php?p = contact。因此,脚本不知道发生了任何重写 - 它仍然被称为“通常”的方式。因此这样的重写将起作用。您可能希望将其视为重写代理,请求与原始浏览器请求的页面不同的页面。
答案 3 :(得分:1)
当客户端请求http://example.com/contact时,服务器会使用重写规则来代替它们http://example.com/index.php?p=contact。客户端将无法看到重写的URL,甚至可能无法判断它是否已被重写。请求任一URL作为客户端将为您提供完全相同的页面。
答案 4 :(得分:0)
您将网址从/contact
重写为/index.php?p=contact
,是的,它会按预期工作。
答案 5 :(得分:0)
是不是在渲染页面部分后修改标题会导致php页面出现问题?你是如何重写URL的?也许我误解了......
答案 6 :(得分:-2)
在你的情况下它不起作用。 mod_rewrite在找到匹配项并将http://example.com/index.php?p=contact重写为http://example.com/contact后,执行内部重定向。即使在重定向之后,新的重定向URI仍然可以与条件匹配并进一步重定向。
在任何情况下,传入的URI都不会保留在内存中,因此即使Apache也无法重建原始URI的内容。 PHP在执行时也不知道原始URI。因此,您丢失了$ _GET变量,因为通过 GET 发送的变量包含在URL中,到目前为止,它已被转换,并且PHP通过解析传入的请求来填充关联的$ _GET数组。
为两者提供支持将是艰苦的。如果您有http://domain.com/segment1/segment2/segment3,则必须将这些细分与有意义的细分相关联。您将剥离域名并在'/'上展开,在您的情况下,您可以说第一个段请求页面,而http://example.com/contact/您可以提取page ='contact'