Przekazywanie tablic jako parametru url


115

Jaki jest najlepszy sposób przekazania tablicy jako parametru adresu URL? Zastanawiałem się, czy to możliwe:

$aValues = array();

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

lub co powiesz na to:

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

Czytałem przykłady, ale uważam, że to niechlujne:

$url = 'http://www.example.com?aParam[]=value1&aParam[]=value2&aParam[]=value3';

2
Dlaczego nie możesz po prostu przejść $_POST?
losowy

To naprawdę wygląda niechlujnie. Ale dla takiego podejścia musi być. Inne podejście, mało skomplikowane, to przypisanie query = array('aParam'=> json_encode($arrayOfValues)). I że możesz przekazać ładniejszy adres URL za pomocą url_encode(implode('/',$query)). Adres URL będzie wyglądał jak www.example.com/aParam/[va1,val2,...]. Przy odbiorze musisz wpisać wartość json_decode aParam do tablicy.
Vladimir Vukanac

Odpowiedzi:


220

Jest bardzo proste rozwiązanie: http_build_query(). Pobiera parametry zapytania jako tablicę asocjacyjną:

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

wróci

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

http_build_query()obsługuje wszystkie niezbędne znaki ucieczki ( %5B=> [i %5D=> ]), więc ten ciąg jest równy aParam[0]=1&aParam[1]=4&aParam[a]=b&aParam[c]=d.


16
Jeśli zastanawiasz się, jak przywrócić to z powrotem do tablicy, odpowiedzią jest parse_str () .
Typo

1
Użyłem tego do umieszczenia adresu URL w tablicy, ale nie wiem, jak odzyskać dane. Próbowałem parse_str i nie mogłem go uruchomić. Myślę, że byłaby to cenna informacja
Thomas Williams

2
Dla każdego, kto ma problemy z http_build_querypowrotem param[]i czasami param[index]. Sprawdź ten post: stackoverflow.com/questions/11996573/…
stwhite

2
aby odzyskać wartość, którą musisz po prostu $ data = $ _GET ['aParam'];
dfortun

@dfortun get back jest ważne, że zaoszczędziłeś dużo czasu parse_str () nie działało dla mnie, ale $ data = $ _GET ['aParam']; jest właściwym rozwiązaniem
Asesha George

56

Edycja: Nie przegap powyższego rozwiązania Stefana, które wykorzystuje bardzo przydatną http_build_query()funkcję: https://stackoverflow.com/a/1764199/179125

Knittl ma rację co do ucieczki. Można to jednak zrobić w prostszy sposób:

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

Jeśli chcesz to zrobić z tablicą asocjacyjną, spróbuj zamiast tego:

PHP 5.3+ (funkcja 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 (wywołanie zwrotne)

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

1
schludny! byłoby miło, gdyby to działało również z tablicami asocjacyjnymi. W każdym razie +1
knittl

3
knittl: Możemy to zrobić za pomocą funkcji zwrotnej do array_map i osobno przekazując klucze i wartości. Sprawdź to.
Jordan działa

ale to może nadal przekraczać maksymalny rozmiar parametru GET, prawda? jakie są szanse, jeśli zamiast tego użyję sesji, tak jak wspomniany poniżej Nash?
uji

Cóż, możesz przechowywać mniej więcej nieograniczoną ilość danych w sesji. Ryzyko związane z sesjami polega na tym, że adresy URL pękają po wygaśnięciu sesji lub gdy użytkownik próbuje coś zrobić, np. W dwóch kartach jednocześnie. Jeśli użytkownik doda stronę do zakładek, a następnie wróci po wygaśnięciu sesji, czy nadal otrzyma oczekiwaną stronę? Wygląda na to, że być może będziesz musiał bardziej pomyśleć o swojej architekturze i po pierwsze, dlaczego omijasz tak ogromne tablice.
Jordan działa

+1 dobra odpowiedź i praca dla mnie również po roku od opublikowania tej odpowiedzi.
Naveed

10

Najłatwiej byłoby użyć serializefunkcji.

Serializuje dowolną zmienną do przechowywania lub przesyłania. Możesz o tym poczytać w podręczniku php - serializuj

Zmienną można przywrócić za pomocą unserialize

Tak więc przy przejściu do adresu URL, którego używasz:

$url = urlencode(serialize($array))

i przywrócić używaną zmienną

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

Uważaj jednak tutaj. Maksymalny rozmiar żądania GET jest ograniczony do 4k, który można łatwo przekroczyć, przekazując tablice w adresie URL.

Poza tym naprawdę nie jest to najbezpieczniejszy sposób przesyłania danych! Zamiast tego prawdopodobnie powinieneś rozważyć użycie sesji.


serializowanie to również fajny sposób na zrobienie tego, ale potem jest już w nie tak czytelnej formie
knittl

1
Tak, serializacja nie jest tak naprawdę czystym sposobem robienia rzeczy podczas pracy z adresami URL, ponieważ tak bardzo rozszerza dane. Lepiej iść na zamówienie.
Kzqai

martwiłem się o maksymalny rozmiar parametru GET, dlatego (głupio) miałem nadzieję, że parser nie będzie miał nic przeciwko, jeśli jest to przekazana tablica. Dopiero teraz zdałem sobie sprawę, że nie zadziała bez dotykania maksymalnego rozmiaru. W każdym razie dzięki nash, myślę, że zrobię to z sesjami
uji

4
Naprawdę nie powinieneś przekazywać niezaufanych danych do funkcji unserialize (). Spróbuj zamiast tego json_encode () i json_decode ().
Mikko Rantalainen

6

prosimy o unikanie zmiennych podczas wyprowadzania ( urlencode).

i nie możesz po prostu wydrukować tablicy, musisz w jakiś sposób zbudować swój adres URL za pomocą pętli

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

1
Zamiast używać zmiennej „pierwszej” do pominięcia pierwszej zmiennej & amp;, możesz użyć tymczasowej tablicy do przechowywania wartości i użyć implode po słowie. Tylko dla czytelności. 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"; daje 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";} i

print $strenc . "\n"; daje

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

Jeśli więc chcesz przekazać to $arrayprzez adres URL do page_no_2.php,

dawny:-

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

Aby powrócić do oryginalnej tablicy, to musi być urldecode(), a potem unserialize(), jak to w page_no_2.php:

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

daje

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

ponownie: D



1

To nie jest bezpośrednia odpowiedź, ponieważ już na to odpowiedziano, ale wszyscy mówili o wysyłaniu danych, ale nikt tak naprawdę nie powiedział, co robisz, kiedy się tam dostanie, a wypracowanie tego zajęło mi dobre pół godziny. Więc pomyślałem, że pomogę tutaj.

Powtórzę to trochę

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

Oczywiście sformatowałbyś go lepiej niż ten www.someurl.com?x=$query

I odzyskać dane

parse_str($_GET['x']);
echo $mydata['dog'];
echo $mydata['cat'];

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'];

0

na otrzymanej stronie możesz użyć:

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


Witamy w Stack Overflow. Dodając odpowiedź na pytanie sprzed dziesięciu lat z ośmioma innymi odpowiedziami, bardzo ważne jest wskazanie, jakiego nowego aspektu pytania dotyczy twoja odpowiedź. Obecnie wygląda na to, że masz odpowiedź zawierającą tylko kod, która została już uwzględniona w jednej z pozostałych odpowiedzi. Proszę używać formatowania kodu dla kodu w przyszłych odpowiedziach.
Jason Aller

0

To kolejny sposób rozwiązania tego problemu.

$data = array(
              1,
              4,
             'a' => 'b',
             'c' => 'd'
              );
$query = http_build_query(array('aParam' => $data));
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.