Передача масивів як параметр url


115

Який найкращий спосіб передати масив як параметр url? Я думав, чи можливо це:

$aValues = array();

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

або як щодо цього:

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

Я читаю приклади, але вважаю це безладним:

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

2
Чому ти не можеш просто пройти $_POST?
випадково

Це справді виглядає безладно. Але для такого підходу це має бути. Інший підхід, малоскладний - призначити query = array('aParam'=> json_encode($arrayOfValues)). І що ви можете передати в приємніший URL url_encode(implode('/',$query)). URL буде виглядати так www.example.com/aParam/[va1,val2,...]. При отриманні вам потрібно json_decode значення aParam в масив.
Володимир Вуканак

Відповіді:


220

Існує дуже просте рішення: http_build_query(). Він приймає параметри запиту як асоціативний масив:

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

повернеться

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

http_build_query()обробляє всі необхідні для вас епізоди ( %5B=> [і %5D=> ]), тому ця рядок дорівнює aParam[0]=1&aParam[1]=4&aParam[a]=b&aParam[c]=d.


16
Якщо вам цікаво, як повернути це в масив, відповідь - parse_str () .
Typo

1
Я використовував це для введення URL-адреси в масив, але не знаю, як повернути дані. Я спробував parse_str і не зміг його працювати. Я думаю, що це була б цінна інформація
Томас Вільямс

2
Для тих, хто стикається з проблемами http_build_queryповернення param[]та іноді param[index]. Перевірте цей пост: stackoverflow.com/questions/11996573 / ...
stwhite

2
щоб повернути значення, яке вам потрібно просто $ data = $ _GET ['aParam'];
dfortun

@dfortun повернутися важливо, що ви заощадили багато часу parse_str () не працював для мене, але $ data = $ _GET ['aParam']; правильне рішення
Асеша Джордж

56

Редагувати: Не пропустіть рішення Стефана вище, яке використовує дуже зручну http_build_query()функцію: https://stackoverflow.com/a/1764199/179125

трикотаж прямо про втечу. Однак є простіший спосіб зробити це:

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

Якщо ви хочете зробити це з асоціативним масивом, спробуйте це замість цього:

PHP 5.3+ (лямбда-функція)

$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 (зворотний дзвінок)

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
акуратний! Було б добре, якби це могло працювати і з асоціативними масивами. +1 у будь-якому випадку
knittl

3
knittl: Ми можемо це зробити за допомогою функції зворотного виклику для array_map та передачі ключів та значень окремо. Перевір.
Йорданія, що працює

але це все-таки може перевищувати максимальний розмір параметра GET? які шанси, якщо я замість цього використовую сеанси так само, як наш, згаданий нижче?
uji

Ну, ви можете зберігати більш-менш необмежену кількість даних у сеансі. Ризик, пов’язаний із сеансами, полягає в порушенні URL-адрес, коли сеанс закінчується, або якщо користувач намагається робити щось, наприклад, на двох вкладках одночасно. Якщо користувач додає закладки на сторінку, а потім повернеться після закінчення сеансу, вони все-таки отримають ту сторінку, яку вони очікують? Здається, що вам може знадобитися думати більше про свою архітектуру і чому ви в першу чергу обходите такі величезні масиви.
Йорданія, що працює

+1 хороша відповідь і працює для мене також через рік після публікації цієї відповіді.
Naveed

10

Найпростішим способом було б використання serializeфункції.

Він серіалізує будь-яку змінну для зберігання чи передачі. Ви можете прочитати про це в посібнику по php - серіалізуйте

Змінна може бути відновлена ​​за допомогою unserialize

Отже, переходячи до URL-адреси, яку ви використовуєте:

$url = urlencode(serialize($array))

і відновити використану змінну

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

Але будьте обережні тут. Максимальний розмір GET-запиту обмежений 4 к, який ви можете легко перевищити, передаючи масиви в URL.

Крім того, це дійсно не зовсім безпечний спосіб передачі даних! Ви, мабуть, повинні вивчити використання сеансів замість цього.


серіалізація - це також приємний спосіб зробити це, але тоді це вже не в такому
читаному

1
Так, серіалізація насправді не є чистим способом виконання справ, коли ви працюєте з URL-адресами, оскільки вона настільки розширює дані. Краще йти на замовлення.
Kzqai

Максимальний розмір параметра GET - це те, що я хвилювався через те, чому я (дурно) сподівався, що аналізатор не буде мати думки, якщо його буде передано масив. Я зараз зрозумів, що це не буде працювати, не торкаючись максимального розміру. Все одно дякую, я думаю, що я буду це робити з сеансами
uji

4
Ви дійсно не повинні передавати недовірені дані для несеріалізації (). Спробуйте скористатися json_encode () та json_decode ().
Мікко Ранталайнен

6

будь ласка, уникайте своїх змінних при виведенні ( urlencode).

і ви не можете просто надрукувати масив, ви повинні побудувати URL-адресу, використовуючи цикл певним чином

$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
Замість використання змінної "first" для пропуску першого & amp; ви можете використовувати тимчасовий масив для зберігання своїх значень та використання післясловів implode. Просто для читабельності. php.net/implode
наш

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";} і

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

Тож якщо ви хочете передати це $arrayчерез URL page_no_2.php,

колишній: -

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

Для того, щоб повернутися назад у вихідний масив, він повинен бути urldecode(), то unserialize(), як це в 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"
}

знову: D



1

Це не пряма відповідь, оскільки на це вже відповіли, але всі говорили про надсилання даних, але ніхто насправді не сказав, що ти робиш, коли потрапляєш туди, і мені знадобилося півгодини, щоб я це розробив. Тому я думав, що допоможу тут.

Я повторю це трохи

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

Очевидно, ви б відформатували його краще, ніж цей www.someurl.com?x=$query

І щоб повернути дані

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

на отриманій сторінці ви можете використовувати:

parse_str ($ str, $ масив); var_dump ($ масив);


Ласкаво просимо до переповнення стека. Додаючи відповідь на десятирічне запитання з вісьмома іншими відповідями, дуже важливо вказати, який новий аспект питання стосується вашої відповіді. Зараз схоже на те, що у вас є лише відповідь на код, яка вже була охоплена однією з інших відповідей. Будь ласка, використовуйте форматування коду для коду в майбутніх відповідях.
Джейсон Аллер

0

Це ще один спосіб вирішення цієї проблеми.

$data = array(
              1,
              4,
             'a' => 'b',
             'c' => 'd'
              );
$query = http_build_query(array('aParam' => $data));
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.