如何从PHP中的URL获取具有相同名称的多个参数

我有一个PHP应用程序,有时必须处理URL中的多个参数具有相同名称的URL。 有一个简单的方法来检索给定的键的所有值? PHP $ _GET只返回最后一个值。

为了使这个具体,我的应用程序是一个OpenURL的parsing器,并可能获得像这样的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 

(是的,我知道这很丑,欢迎来到我的世界)。 请注意,密钥“rft_id”出现两次:

  1. rft_id=info:oclcnum/1903126
  2. rft_id=http://www.biodiversitylibrary.org/bibliography/4323

$_GET将返回只是http://www.biodiversitylibrary.org/bibliography/4323 ,较早的值( info:oclcnum/1903126 )已被覆盖。

我想获得这两个值。 这是可能的PHP? 如果没有,关于如何处理这个问题的任何想法?

就像是:

 $query = explode('&', $_SERVER['QUERY_STRING']); $params = array(); foreach( $query as $param ) { list($name, $value) = explode('=', $param, 2); $params[urldecode($name)][] = urldecode($value); } 

给你:

 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') ) 

不会为你工作,因为它看起来像你不控制查询string,但另一个有效的答案:而不是parsing查询string,你可以附加'[]'的名称的末尾,然后PHP将使数组的项目。

IE:

 someurl.php?name[]=aaa&name[]=bbb 

会给你一个$ _GET看起来像:

 array(0=>'aaa', 1=>'bbb') 

我想你必须手动parsing$_SERVER['QUERY_STRING']

像(未经testing的):

 $query = $_SERVER['QUERY_STRING']; $vars = array(); foreach (explode('&', $query) as $pair) { list($key, $value) = explode('=', $pair); $vars[] = array(urldecode($key), urldecode($value)); } 

这应该给你一个数组$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') ) 

看到Tomalak的回答后,我更喜欢他的数组格式,因为它可以通过名字访问特定的键。

没有必要为此使用愚蠢的explode解决方法。 一个简单的正则expression式可以更容易地纠正一个QUERY_STRING与多个相似的命名参数:

 // Replace `&x=1&x=2` into `x[]=1&x[]=2` $qs = preg_replace("/(?<=^|&)(\w+)(?==)/", "$1[]", $_SERVER["QUERY_STRING"]); 

那么就像使用parse_str一样简单:

 parse_str($qs, $new_GET); 

这具有正确解码%xy URL转义的优点。

如果您只想将一个或几个特定的​​参数提取为数组,则在正则expression式中使用(id|name)而不是(\w+)

AFAIK没有办法使用$_GET获取重复值,因为第二个值会覆盖第一个值

为了避开它,你可以使用$_SERVER['QUERY_STRING']来访问原始查询string,然后自己parsing它。

假设你有一个这样的查询string:

参数1 = 2549&APPNAME = APPNAME1&APPNAME = appName2&APPNAME = appName3&APPNAME = appName4&APPNAME = appName5&的AppType = thetype&idsess = 1231324567980147dzeze55sd4和行动= myaction

你可以这样做 :

 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); } 

这给了:

 array ( 'param1' => '2549', 'appname' => array ( 0 => 'appName1', 1 => 'appName2', 2 => 'appName3', 3 => 'appName4', 4 => 'appName5', ), 'apptype' => 'thetype', 'idsess' => '1231324567980147dzeze55sd4', 'action' => 'myaction', ); 

希望有所帮助;)

分享我的这个function的版本

 function parse_mstr($query_string,&$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(isset($query[$k])){ if(is_array($query[$k])){ $query[$k][] = $v; }else{ $query[$k] = array($query[$k],$v); } }else{ $query[$k] = $v; } } }