Pasando matrices como parámetro de URL

115

¿Cuál es la mejor manera de pasar una matriz como parámetro de URL? Estaba pensando si esto es posible:

$aValues = array();

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

o que tal esto:

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

He leído ejemplos, pero lo encuentro complicado:

$url = 'http://www.example.com?aParam[]=value1&aParam[]=value2&aParam[]=value3';
uji
fuente
2
¿Por qué no puedes pasar $_POST?
aleatorio
Esto realmente se ve desordenado. Pero para ese enfoque tiene que serlo. Otro enfoque, poco complicado, es asignar query = array('aParam'=> json_encode($arrayOfValues)). Y con la que puedes pasar una URL más agradable url_encode(implode('/',$query)). La URL se verá así www.example.com/aParam/[va1,val2,...]. Al recibir, debe json_decode aParam value en una matriz.
Vladimir Vukanac

Respuestas:

220

Hay una solución muy simple: http_build_query(). Toma sus parámetros de consulta como una matriz asociativa:

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

volverá

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

http_build_query()maneja todos los escapes necesarios para usted ( %5B=> [y %5D=> ]), por lo que esta cadena es igual a aParam[0]=1&aParam[1]=4&aParam[a]=b&aParam[c]=d.

Stefan Gehrig
fuente
16
Si se pregunta cómo volver a incluir esto en una matriz, la respuesta es parse_str () .
Typo
1
He usado esto para poner la URL en la matriz pero no sé cómo recuperar los datos. Intenté parse_str y no pude hacerlo funcionar. Creo que esta sería información valiosa
Thomas Williams
2
Para cualquiera que tenga problemas con el http_build_queryregreso param[]y algunas veces param[index]. Echa un vistazo a esta publicación: stackoverflow.com/questions/11996573/…
stwhite
2
para recuperar el valor solo tiene que $ data = $ _GET ['aParam'];
dfortun
@dfortun get back es importante, ahorró mucho tiempo parse_str () no funcionó para mí, pero $ data = $ _GET ['aParam']; es la solución correcta
Asesha George
56

Editar: no se pierda la solución de Stefan anterior, que utiliza la http_build_query()función muy útil : https://stackoverflow.com/a/1764199/179125

Knittl tiene razón sobre cómo escapar. Sin embargo, hay una forma más sencilla de hacer esto:

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

Si desea hacer esto con una matriz asociativa, intente esto en su lugar:

PHP 5.3+ (función 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 (devolución de llamada)

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 corriendo
fuente
1
¡ordenado! Sería bueno si también pudiera funcionar con matrices asociativas. +1 de todos modos
Knittl
3
knittl: Podemos hacer eso con una función de devolución de llamada a array_map y pasando las claves y los valores por separado. Echale un vistazo.
Jordan Running
pero esto aún podría exceder el tamaño máximo del parámetro GET, ¿verdad? ¿Cuáles son las probabilidades si uso sesiones en su lugar como se menciona a continuación?
uji
Bueno, puedes almacenar una cantidad de datos más o menos ilimitada en una sesión. El riesgo de las sesiones es que las URL se rompan cuando la sesión expira o si el usuario intenta hacer cosas, por ejemplo, en dos pestañas a la vez. Si el usuario marca la página como favorita y luego vuelve después de que expira su sesión, ¿seguirá recibiendo la página que espera? Parece que es posible que deba pensar más en su arquitectura y por qué está distribuyendo matrices tan grandes en primer lugar.
Jordan Running
+1 buena respuesta y trabajando para mí también después de un año de publicar esta respuesta.
Naveed
10

La forma más sencilla sería utilizar la serializefunción.

Serializa cualquier variable para su almacenamiento o transferencia. Puede leer sobre esto en el manual de php - serialize

La variable se puede restaurar usando unserialize

Entonces, al pasar a la URL que usa:

$url = urlencode(serialize($array))

y para restaurar la variable que usa

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

Sin embargo, ten cuidado aquí. El tamaño máximo de una solicitud GET está limitado a 4k, que puede superar fácilmente al pasar matrices en una URL.

Además, ¡no es la forma más segura de pasar datos! Probablemente debería considerar el uso de sesiones en su lugar.

Nash
fuente
serializar también es una buena forma de hacerlo, pero luego ya no está en una forma tan legible
knittl
1
Sí, serializar no es realmente una forma limpia de hacer las cosas cuando se trabaja con direcciones URL, porque expande mucho los datos. Es mejor personalizarlo.
Kzqai
el tamaño máximo del parámetro GET era lo que me preocupaba, por eso estaba (estúpidamente) esperando que al analizador no le importara si se pasa una matriz. Me di cuenta de que no funcionará sin tocar el tamaño máximo. Gracias de todos modos nash, creo que lo haré con sesiones
uji
4
Realmente no debería pasar datos que no sean de confianza a unserialize (). Pruebe json_encode () y json_decode () en su lugar.
Mikko Rantalainen
6

por favor escape sus variables al generar ( urlencode).

y no puede simplemente imprimir una matriz, debe construir su URL usando un bucle de alguna manera

$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);
}
Knittl
fuente
1
En lugar de usar una "primera" variable para omitir la primera & amp;, puede usar una matriz temporal para almacenar sus valores y usar las palabras posteriores de implosión. Solo por legibilidad. 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"; da 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";} y

print $strenc . "\n"; da

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

Entonces, si desea pasar esto a $arraytravés de una URL a page_no_2.php,

ex:-

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

Para volver a la matriz original, debe ser urldecode(), entonces unserialize(), así en page_no_2.php:

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

da

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

de nuevo: D

Thusitha Sumanadasa
fuente
1

Esta no es una respuesta directa, ya que esto ya ha sido respondido, pero todos hablaban de enviar los datos, pero nadie dijo realmente lo que haces cuando llegan allí, y me tomó una buena media hora resolverlo. Así que pensé en ayudar aquí.

Voy a repetir esto

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

Obviamente, lo formatearías mejor que este www.someurl.com?x=$query

Y recuperar los datos

parse_str($_GET['x']);
echo $mydata['dog'];
echo $mydata['cat'];
Thomas Williams
fuente
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'];
usuario2638158
fuente
0

en la página recibida puede utilizar:

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

CarlosP
fuente
Bienvenido a Stack Overflow. Al agregar una respuesta a una pregunta de hace diez años con otras ocho respuestas, es muy importante señalar qué aspecto nuevo de la pregunta aborda su respuesta. En este momento, parece que tiene una respuesta de solo código que ya ha sido cubierta por una de las otras respuestas. Utilice el formato de código para el código en futuras respuestas.
Jason Aller
0

Esta es otra forma de solucionar este problema.

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