简体   繁体   English

PHP-具有多个参数和相同名称的URL导致意外行为

[英]PHP - URL with multiple parameters and same name causing unexpected behaviour

I have a Rewrite Rule as 我有一个重写规则为

RewriteRule settings/([a-zA-Z0-9_]+)/?$ settings/?path=$1 [NC,L,QSA]

It basically takes path parameter and rewrite url like this http://localhost/settings/?path=abc => http://localhost/settings/abc 它基本上需要路径参数并像这样http://localhost/settings/?path=abc => http://localhost/settings/abc重写URL

But there's a problem! 但是有一个问题! when I provide something like http://localhost/settings/abc/?path=xyz the path parameter is overwritten with xyz and it opens http://localhost/settings/abc/ with data of xyz 当我提供类似http://localhost/settings/abc/?path=xyz的内容时,路径参数会被xyz覆盖,并且会使用数据xyz打开http://localhost/settings/abc/

After further digging I noticed that the problem is caused by the parameters in URL itself. 进一步挖掘后,我注意到问题是由URL本身的参数引起的。 By default its picking up the value of last parameter with same name http://localhost/settings/account/?path=profile&path=account&path=profile 默认情况下,它会选择具有相同名称http://localhost/settings/account/?path=profile&path=account&path=profile的最后一个参数的值

so the value that i can get in this case for $_REQUEST['path'] is profile . 所以在这种情况下,我可以为$_REQUEST['path']获得的值是profile How can I just pickup the first value from the same parameters and ignore the rest of them? 我该如何从相同的参数中选取第一个值,而忽略其余参数?

One thing I can do is to remove [QSA] from the RewriteRule , that will do the fix but I need other parameters passed in url as well. 我可以做的一件事是从RewriteRule删除[QSA] ,它可以解决问题,但我也需要在url中传递其他参数。

How can I achieve this? 我该如何实现?

PHP recognizes brackets [] appended to a parameter, eg PHP可以识别附加到参数的方括号[] ,例如

http://localhost/settings/account/?path[]=profile&path[]=account&path[]=profile

will be translated into an array 将被转换成数组

$path = $_GET['path'];
print_r($path);

shows 节目

Array ( [0] => profile [1] => account [2] => profile ) 数组([0] =>个人资料[1] =>帐户[2] =>个人资料)

This way, you can access any of the "paths" you like. 这样,您可以访问所需的任何“路径”。


I could imagine some RewriteCond surgery, in order to remove part of a query string 我可以想象要进行一些RewriteCond手术,以便删除查询字符串的一部分

RewriteCond %{QUERY_STRING} ^(.*)&path=.*?&(.*)$
RewriteRule ^ %{REQUEST_URI}?%1&%2

RewriteCond %{QUERY_STRING} ^path=.*?&(.*)$
RewriteRule ^ %{REQUEST_URI}?%1

RewriteCond %{QUERY_STRING} ^(.*)&path=.*$
RewriteRule ^ %{REQUEST_URI}?%1

Depending on where the path is, this would remove it from the query string. 根据path位置,这会将其从查询字符串中删除。 And finally, the last rule would add the new path again 最后,最后一条规则将再次添加新路径

RewriteRule settings/([a-zA-Z0-9_]+)/?$ settings/?path=$1 [NC,L,QSA]

Although, I don't know, if this is working at all, and how (in)efficient this is. 虽然,我不知道这是否有效,效率如何(低效)。

There is one caveat, you must check for REDIRECT_STATUS to prevent an endless loop. 有一个警告,您必须检查REDIRECT_STATUS以防止无限循环。

You can use these 2 rules in your .htaccess: 您可以在.htaccess中使用以下2条规则:

# remove path= parameter from query string, if it exists
RewriteCond %{THE_REQUEST} \?(.*&)?path=[^&]*(?:&(.*))?$ [NC]
RewriteRule ^settings/. %{REQUEST_URI}?%1%2 [L,R=301,NE,NC]

# your existing rule
RewriteCond %{THE_REQUEST} \?(.*&)?path=[^&]*(?:&(\S*))? [NC]
RewriteRule ^settings/ %{REQUEST_URI}?%1%2 [L,R=302,NE,NC]

RewriteCond %{QUERY_STRING} !(?:^|&)path= [NC]
RewriteRule ^(settings)/(\w*)/?$ $1/?path=$2 [NC,L,QSA]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM