php 如何从PHP中的URL获取多个具有相同名称的参数
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/353379/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to get multiple parameters with same name from a URL in PHP
提问by rdmpage
I have a PHP application that will on occasion have to handle URLs where more than one parameter in the URL will have the same name. Is there an easy way to retrieve all the values for a given key? PHP $_GET returns only the last value.
我有一个 PHP 应用程序,它有时必须处理 URL 中多个参数具有相同名称的 URL。有没有一种简单的方法来检索给定键的所有值?PHP $_GET 只返回最后一个值。
To make this concrete, my application is an OpenURL resolver, and may get URL parameters like this:
具体来说,我的应用程序是一个 OpenURL 解析器,并且可能会获取如下 URL 参数:
ctx_ver=Z39.88-2004
&rft_id=info:oclcnum/1903126
&rft_id=http://www.biodiversitylibrary.org/bibliography/4323
&rft_val_fmt=info:ofi/fmt:kev:mtx:book
&rft.genre=book
&rft.btitle=At last: a Christmas in the West Indies.
&rft.place=London,
&rft.pub=Macmillan and co.,
&rft.aufirst=Charles
&rft.aulast=Kingsley
&rft.au=Kingsley, Charles,
&rft.pages=1-352
&rft.tpages=352
&rft.date=1871
(Yes, I know it's ugly, welcome to my world). Note that the key "rft_id" appears twice:
(是的,我知道这很丑,欢迎来到我的世界)。请注意,键“rft_id”出现了两次:
rft_id=info:oclcnum/1903126rft_id=http://www.biodiversitylibrary.org/bibliography/4323
rft_id=info:oclcnum/1903126rft_id=http://www.biodiversitylibrary.org/bibliography/4323
$_GETwill return just http://www.biodiversitylibrary.org/bibliography/4323, the earlier value (info:oclcnum/1903126) having been overwritten.
$_GET将仅返回http://www.biodiversitylibrary.org/bibliography/4323,较早的值 ( info:oclcnum/1903126) 已被覆盖。
I'd like to get access to both values. Is this possible in PHP? If not, any thoughts on how to handle this problem?
我想访问这两个值。这在 PHP 中可能吗?如果没有,关于如何处理这个问题的任何想法?
回答by Tomalak
Something like:
就像是:
$query = explode('&', $_SERVER['QUERY_STRING']);
$params = array();
foreach( $query as $param )
{
// prevent notice on explode() if $param has no '='
if (strpos($param, '=') === false) $param += '=';
list($name, $value) = explode('=', $param, 2);
$params[urldecode($name)][] = urldecode($value);
}
gives you:
给你:
array(
'ctx_ver' => array('Z39.88-2004'),
'rft_id' => array('info:oclcnum/1903126', 'http://www.biodiversitylibrary.org/bibliography/4323'),
'rft_val_fmt' => array('info:ofi/fmt:kev:mtx:book'),
'rft.genre' => array('book'),
'rft.btitle' => array('At last: a Christmas in the West Indies.'),
'rft.place' => array('London'),
'rft.pub' => array('Macmillan and co.'),
'rft.aufirst' => array('Charles'),
'rft.aulast' => array('Kingsley'),
'rft.au' => array('Kingsley, Charles'),
'rft.pages' => array('1-352'),
'rft.tpages' => array('352'),
'rft.date' => array('1871')
)
Since it's always possible that one URL parameter is repeated, it's better to always have arrays, instead of only for those parameters where you anticipate them.
因为总是有可能重复一个 URL 参数,所以最好总是有数组,而不是只为那些您期望它们的参数。
回答by benlumley
Won't work for you as it looks like you don't control the querystring, but another valid answer: Instead of parse querystring, you could appeand '[]' to the end of the name, then PHP will make an array of the items.
对您不起作用,因为您似乎无法控制查询字符串,但另一个有效答案是:您可以将 '[]' 添加到名称末尾,而不是解析查询字符串,然后 PHP 将创建一个数组项目。
IE:
IE:
someurl.php?name[]=aaa&name[]=bbb
will give you a $_GET looking like:
会给你一个 $_GET 看起来像:
array(0=>'aaa', 1=>'bbb')
回答by Stefan Gehrig
I think you'd have to parse $_SERVER['QUERY_STRING']manually.
我认为您必须$_SERVER['QUERY_STRING']手动解析。
Something like (untested):
类似的东西(未经测试):
$query = $_SERVER['QUERY_STRING'];
$vars = array();
foreach (explode('&', $query) as $pair) {
list($key, $value) = explode('=', $pair);
$vars[] = array(urldecode($key), urldecode($value));
}
This should give you an array $vars:
这应该给你一个数组$vars:
array(
array('ctx_ver' => 'Z39.88-2004'),
array('rft_id' => 'info:oclcnum/1903126'),
array('rft_id' => 'http://www.biodiversitylibrary.org/bibliography/4323'),
array('rft_val_fmt' => 'info:ofi/fmt:kev:mtx:book'),
array('rft.genre' => 'book'),
array('rft.btitle' => 'At last: a Christmas in the West Indies.'),
array('rft.place' => 'London'),
array('rft.pub' => 'Macmillan and co.'),
array('rft.aufirst' => 'Charles'),
array('rft.aulast' => 'Kingsley'),
array('rft.au' => 'Kingsley, Charles'),
array('rft.pages' => '1-352'),
array('rft.tpages' => '352'),
array('rft.date' => '1871')
)
After having seen Tomalak'sanswer, I like his data format for the resulting array much better, as it makes it possible to access specific keys by their name.
看过Tomalak 的回答后,我更喜欢他的结果数组的数据格式,因为它可以通过名称访问特定键。
回答by mario
There's no need to use explodeworkarounds for this. A simple regex can more easily rectify a QUERY_STRING with multiple like-named parameters:
没有必要为此使用explode变通方法。一个简单的正则表达式可以更轻松地使用多个类似命名的参数来纠正 QUERY_STRING:
// Replace `&x=1&x=2` into `x[]=1&x[]=2`
$qs = preg_replace("/(?<=^|&)(\w+)(?==)/", "[]", $_SERVER["QUERY_STRING"]);
Then it's as simple as using parse_str:
然后就像使用一样简单parse_str:
parse_str($qs, $new_GET);
Which has the advantage of correctly decoding %xyURL escapes right away.
这具有立即正确解码%xyURL 转义的优点。
If you just want a single or a few specific parameters extracted as array, then use (id|name)instead of (\w+)in the regex.
如果您只想将单个或几个特定参数提取为数组,请在正则表达式中使用(id|name)代替(\w+)。
回答by Neil Aitken
AFAIK there is no way to get duplicate values using $_GETas the second value will overwrite the first
AFAIK 没有办法使用重复值,$_GET因为第二个值将覆盖第一个
To get around it you could access the raw querystring using $_SERVER['QUERY_STRING']and then parse it yourself.
要解决它,您可以使用访问原始查询字符串$_SERVER['QUERY_STRING'],然后自己解析它。
回答by MonsterDev
Assumed you have a query string like this:
假设你有一个这样的查询字符串:
param1=2549&appname=appName1&appname=appName2&appname=appName3&appname=appName4&appname=appName5&apptype=thetype&idsess=1231324567980147dzeze55sd4&action=myaction
param1=2549&appname=appName1&appname=appName2&appname=appName3&appname=appName4&appname=appName5&apptype=thetype&idsess=1231324567980147dzeze55sd4&action=myaction
You can do this :
你可以这样做 :
public static function getMultipleParameters()
{
$query = $_SERVER['QUERY_STRING'];
$vars = array();
$second = array();
foreach (explode('&', $query) as $pair) {
list($key, $value) = explode('=', $pair);
if('' == trim($value)){
continue;
}
if (array_key_exists($key, $vars)) {
if (!array_key_exists($key, $second))
$second[$key][] .= $vars[$key];
$second[$key][] = $value;
} else {
$vars[$key] = urldecode($value);
}
}
return array_merge($vars, $second);
}
That gives :
这给出了:
array (
'param1' => '2549',
'appname' =>
array (
0 => 'appName1',
1 => 'appName2',
2 => 'appName3',
3 => 'appName4',
4 => 'appName5',
),
'apptype' => 'thetype',
'idsess' => '1231324567980147dzeze55sd4',
'action' => 'myaction',
);
Hope that helps ;)
希望有帮助;)
回答by Timo Huovinen
Sharing my version of this function
分享我的这个功能的版本
function parse_mstr($query_string,&$query=array()){
$query = $query? $query: array();
$params = explode('&', $query_string);
foreach( $params as $param ){
$k = $param;
$v = '';
if(strpos($param,'=')){
list($name, $value) = explode('=', $param);
$k = rawurldecode($name);
$v = rawurldecode($value);
}
if(array_key_exists($k, $query)){
if(is_array($query[$k])){
$query[$k][] = $v;
}else{
$query[$k] = array($query[$k],$v);
}
}else{
$query[$k] = $v;
}
}
}
// usage
parse_mstr('a=1&a=2&b=3', $arr);
// resulting array
$arr = [
'a' => ['1', '2'],
'b' => '3'
]

