У меня есть приложение PHP, которое иногда будет обрабатывать URL-адреса, где более одного параметра в URL-адресе будет иметь одинаковое имя. Есть ли простой способ получить все значения для данного ключа? PHP $ _GET возвращает только последнее значение.
Чтобы сделать это конкретным, мое приложение является распознавателем 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
(Да, я знаю, что это уродливо, добро пожаловать в мой мир). Обратите внимание, что ключ «rft_id» появляется дважды:
rft_id=info:oclcnum/1903126
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') )
Не будет работать для вас, поскольку похоже, что вы не контролируете запрос, но еще один правильный ответ: вместо синтаксического разбора вы можете призывать «[]» к концу имени, тогда PHP будет создавать массив из Предметы.
IE:
someurl.php?name[]=aaa&name[]=bbb
даст вам $ _GET, похожий на:
array(0=>'aaa', 1=>'bbb')
Я думаю, вам придется вручную разбирать $_SERVER['QUERY_STRING']
.
Что-то вроде (непроверено):
$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') )
Увидев ответ Томалака , мне больше нравится его формат данных для результирующего массива, поскольку он позволяет получить доступ к определенным ключам по их имени.
Для этого нет необходимости использовать глупые обходные обходные пути. Простое регулярное выражение может более легко выправить 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);
В чем преимущество правильного декодирования URL-адресов %xy
URL-адресов сразу.
Если вы хотите, чтобы один или несколько определенных параметров были извлечены как массив, используйте (id|name)
вместо (\w+)
в регулярном выражении.
AFAIK нет способа получить повторяющиеся значения, используя $_GET
поскольку второе значение перезапишет первый
Чтобы обойти это, вы можете получить доступ к необработанному querystring с помощью $_SERVER['QUERY_STRING']
а затем проанализировать его самостоятельно.
Предположим, что у вас есть строка запроса:
param1 = 2549 & имя_приложение = appName1 & имя_приложение = appName2 & имя_приложение = appName3 & имя_приложение = appName4 & имя_приложение = 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 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; } } }