Как получить несколько параметров с таким же именем из URL в PHP

голоса
40

У меня есть приложение 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» появляется дважды:

  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? Если нет, то какие-либо мысли о том, как справиться с этой проблемой?

Задан 09/12/2008 в 17:33
источник пользователем
На других языках...                            


7 ответов

голоса
63

Что-то вроде:

$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')
)
Ответил 09/12/2008 в 17:46
источник пользователем

голоса
37

Не будет работать для вас, как это выглядит, как вы не контролируете строку запроса, а другой действительный ответ: Вместо разбора строки запроса, вы можете appeand «[]» в конце имени, то PHP будет сделать массив из Предметы.

IE:

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

даст вам $ _GET выглядит как:

array(0=>'aaa', 1=>'bbb')
Ответил 09/12/2008 в 17:41
источник пользователем

голоса
9

Я думаю , вам придется разобрать $_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')
)

После того , как увидел Томалак в ответ, мне нравится его формат данные для результирующего массива намного лучше, так как это позволяет получить доступ к определенным ключам от их имени.

Ответил 09/12/2008 в 17:37
источник пользователем

голоса
4

Там нет необходимости использовать тупые explodeобходные пути для этого. Простое выражение может легко исправить в 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);

Который имеет преимущество правильного декодирования %xyURL ускользает сразу.

Если вы просто хотите , один или несколько конкретных параметров , извлеченных в виде массива, а затем использовать (id|name)вместо (\w+)в регулярном выражении.

Ответил 21/09/2015 в 17:34
источник пользователем

голоса
2

AFAIK нет никакого способа , чтобы получить повторяющиеся значения , используя в $_GETкачестве второго значения будет перекрывать первый

Для того, чтобы обойти его можно получить доступ к сырой строке запроса с помощью , $_SERVER['QUERY_STRING']а затем разобрать его самостоятельно.

Ответил 09/12/2008 в 17:38
источник пользователем

голоса
1

Разделяя мою версию этой функции

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;
        }
    }
}
Ответил 09/05/2013 в 15:21
источник пользователем

голоса
1

Принято считать, у вас есть строка запроса, как это:

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

Надеюсь, это поможет ;)

Ответил 04/07/2012 в 17:18
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more