Passando matrizes como parâmetro de url

115

Qual é a melhor maneira de passar uma matriz como um parâmetro de url? Eu estava pensando se isso é possível:

$aValues = array();

$url = 'http://www.example.com?aParam='.$aValues;

ou que tal isto:

$url = 'http://www.example.com?aParam[]='.$aValues;

Eu li exemplos, mas acho confuso:

$url = 'http://www.example.com?aParam[]=value1&aParam[]=value2&aParam[]=value3';
uji
fonte
2
Por que você não pode simplesmente passar $_POST?
aleatório de
Isso realmente parece bagunçado. Mas para essa abordagem tem que ser. Outra abordagem, um pouco complicada, é atribuir query = array('aParam'=> json_encode($arrayOfValues)). E com isso você pode passar um url melhor url_encode(implode('/',$query)). O URL ficará assim www.example.com/aParam/[va1,val2,...]. Ao receber, você deve json_decode o valor aParam no array.
Vladimir Vukanac

Respostas:

220

Há uma solução muito simples: http_build_query(). Ele considera seus parâmetros de consulta como uma matriz associativa:

$data = array(
    1,
    4,
    'a' => 'b',
    'c' => 'd'
);
$query = http_build_query(array('aParam' => $data));

retornará

string(63) "aParam%5B0%5D=1&aParam%5B1%5D=4&aParam%5Ba%5D=b&aParam%5Bc%5D=d"

http_build_query()lida com todos os escapes necessários para você ( %5B=> [e %5D=> ]), então esta string é igual a aParam[0]=1&aParam[1]=4&aParam[a]=b&aParam[c]=d.

Stefan Gehrig
fonte
16
Se você está se perguntando como colocar isso de volta em um array, a resposta é parse_str () .
Typo
1
Eu usei isso para colocar o url na matriz, mas não sei como obter os dados de volta. Tentei parse_str e não consegui fazer funcionar. Acho que seria uma informação valiosa
Thomas Williams,
2
Para quem está tendo problemas com o http_build_queryretorno param[]e às vezes param[index]. Confira esta postagem: stackoverflow.com/questions/11996573/…
stwhite
2
para recuperar o valor você só precisa $ data = $ _GET ['aParam'];
infeliz
@ infeliz voltar é importante que você economizou muito tempo parse_str () não funcionou para mim, mas $ data = $ _GET ['aParam']; é a solução correta
Asesha George
56

Editar: não perca a solução de Stefan acima, que usa a http_build_query()função muito útil : https://stackoverflow.com/a/1764199/179125

knittl está certo sobre como escapar. No entanto, há uma maneira mais simples de fazer isso:

$url = 'http://example.com/index.php?';
$url .= 'aValues[]=' . implode('&aValues[]=', array_map('urlencode', $aValues));

Se você quiser fazer isso com uma matriz associativa, tente o seguinte:

PHP 5.3+ (função lambda)

$url = 'http://example.com/index.php?';
$url .= implode('&', array_map(function($key, $val) {
    return 'aValues[' . urlencode($key) . ']=' . urlencode($val);
  },
  array_keys($aValues), $aValues)
);

PHP <5.3 (retorno de chamada)

function urlify($key, $val) {
  return 'aValues[' . urlencode($key) . ']=' . urlencode($val);
}

$url = 'http://example.com/index.php?';
$url .= implode('&amp;', array_map('urlify', array_keys($aValues), $aValues));
Jordan Running
fonte
1
arrumado! seria bom se pudesse funcionar com matrizes associativas também. +1 de qualquer maneira
knittl
3
knittl: Podemos fazer isso com uma função de retorno de chamada para array_map e passando as chaves e valores separadamente. Confira.
Jordan Running em
mas isso ainda pode exceder o tamanho máximo do parâmetro GET certo? Quais são as chances se eu usar sessões como nash mencionadas abaixo?
uji de
Bem, você pode armazenar uma quantidade mais ou menos ilimitada de dados em uma sessão. O risco com as sessões é a quebra de URLs quando a sessão expira ou se o usuário tentar fazer coisas, por exemplo, em duas guias ao mesmo tempo. Se o usuário marcar a página e voltar depois que a sessão expirar, ele ainda obterá a página que esperava? Parece que você precisa pensar mais sobre sua arquitetura e por que está distribuindo matrizes tão grandes em primeiro lugar.
Jordan Running em
+1 boa resposta e trabalhando para mim também após um ano postando esta resposta.
Naveed em
10

A maneira mais fácil seria usar a serializefunção.

Ele serializa qualquer variável para armazenamento ou transferência. Você pode ler sobre isso no manual do php - serialize

A variável pode ser restaurada usando unserialize

Portanto, ao passar para o URL que você usa:

$url = urlencode(serialize($array))

e para restaurar a variável que você usa

$var = unserialize(urldecode($_GET['array']))

Porém, tenha cuidado aqui. O tamanho máximo de uma solicitação GET é limitado a 4k, que você pode facilmente exceder passando matrizes em um URL.

Além disso, não é exatamente a maneira mais segura de passar dados! Você provavelmente deve considerar o uso de sessões.

nash
fonte
serializar também é uma boa maneira de fazer isso, mas agora está em uma forma não tão legível
knittl
1
Sim, serializar não é realmente uma maneira limpa de fazer as coisas quando você está trabalhando com urls, porque expande muito os dados. Melhor personalizar.
Kzqai
O tamanho máximo do parâmetro GET era o que me preocupava, por isso eu estava (estupidamente) esperando que o analisador não se importasse se fosse um array que fosse passado. Eu percebi agora que não vai funcionar sem tocar no tamanho máximo. Obrigado de qualquer forma, acho que farei isso com sessões
uji
4
Você realmente não deve passar dados não confiáveis ​​para unserialize (). Tente json_encode () e json_decode () ao invés.
Mikko Rantalainen,
6

por favor escape suas variáveis ​​quando outputting ( urlencode).

e você não pode simplesmente imprimir um array, você tem que construir seu url usando um loop de alguma forma

$url = 'http://example.com/index.php?'
$first = true;
foreach($aValues as $key => $value) {
  if(!$first) $url .= '&amp';
  else $first = false;
  $url .= 'aValues['.urlencode($key).']='.urlencode($value);
}
tricô
fonte
1
Em vez de usar uma "primeira" variável para pular o primeiro & amp ;, você pode usar um array temporário para armazenar seus valores e usar subseqüentes implodir. Apenas para facilitar a leitura. php.net/implode
nash
5
 <?php
$array["a"] = "Thusitha";
$array["b"] = "Sumanadasa";
$array["c"] = "Lakmal";
$array["d"] = "Nanayakkara";

$str = serialize($array);
$strenc = urlencode($str);
print $str . "\n";
print $strenc . "\n";
?> 

print $str . "\n";a:4:{s:1:"a";s:8:"Thusitha";s:1:"b";s:10:"Sumanadasa";s:1:"c";s:6:"Lakmal";s:1:"d";s:11:"Nanayakkara";} e

print $strenc . "\n";

a%3A4%3A%7Bs%3A1%3A%22a%22%3Bs%3A8%3A%22Thusitha%22%3Bs%3A1%3A%22b%22%3Bs%3A10%3A%22Sumanadasa%22%3Bs%3A1%3A%22c%22%3Bs%3A6%3A%22Lakmal%22%3Bs%3A1%3A%22d%22%3Bs%3A11%3A%22Nanayakkara%22%3B%7D

Então, se você quiser passar isso $arraypor meio de URL para page_no_2.php,

ex:-

$url ='http://page_no_2.php?data=".$strenc."';

Para retornar ao array original, ele precisa ser urldecode(), então unserialize(), assim em page_no_2.php:

    <?php
    $strenc2= $_GET['data'];
    $arr = unserialize(urldecode($strenc2));
    var_dump($arr);
    ?>

 array(4) {
  ["a"]=>
  string(8) "Thusitha"
  ["b"]=>
  string(10) "Sumanadasa"
  ["c"]=>
  string(6) "Lakmal"
  ["d"]=>
  string(11) "Nanayakkara"
}

novamente: D

Assimitha Sumanadasa
fonte
1

Esta não é uma resposta direta, pois já foi respondida, mas todo mundo estava falando em enviar os dados, mas ninguém disse realmente o que você faz quando eles chegam lá, e demorei uma boa meia hora para resolver. Então pensei em ajudar aqui.

Vou repetir esta parte

$data = array(
'cat' => 'moggy',
'dog' => 'mutt'
);
$query = http_build_query(array('mydata' => $data));
$query=urlencode($query);

Obviamente, você iria formatar melhor do que este www.someurl.com?x=$query

E para obter os dados de volta

parse_str($_GET['x']);
echo $mydata['dog'];
echo $mydata['cat'];
Thomas Williams
fonte
0
**in create url page**

$data = array(
        'car' => 'Suzuki',
        'Model' => '1976'
        );
$query = http_build_query(array('myArray' => $data));
$url=urlencode($query); 

echo" <p><a href=\"index2.php?data=".$url."\"> Send </a><br /> </p>";

**in received page**

parse_str($_GET['data']);
echo $myArray['car'];
echo '<br/>';
echo $myArray['model'];
user2638158
fonte
0

na página recebida você pode usar:

parse_str ($ str, $ array); var_dump ($ array);

CarlosP
fonte
Bem-vindo ao Stack Overflow. Ao adicionar uma resposta a uma pergunta de dez anos com oito outras respostas, é muito importante apontar qual novo aspecto da pergunta sua resposta aborda. No momento, parece que você tem uma resposta apenas em código que já foi abordada por uma das outras respostas. Use a formatação de código para o código em respostas futuras.
Jason Aller
0

Essa é outra maneira de resolver esse problema.

$data = array(
              1,
              4,
             'a' => 'b',
             'c' => 'd'
              );
$query = http_build_query(array('aParam' => $data));
Asiamah Amos
fonte