Передача массивов в качестве параметра 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?
random
Это действительно выглядит неаккуратно. Но для такого подхода это должно быть. Другой подход, немного сложный - назначить 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 () .
Опечатка
1
Я использовал это, чтобы поместить URL-адрес в массив, но не знаю, как вернуть данные. Я попробовал parse_str и не смог заставить его работать. Думаю, это была бы ценная информация
Томас Уильямс
2
Для тех, кто сталкивается с проблемами с http_build_queryвозвращением param[]и иногда param[index]. Посмотрите этот пост: stackoverflow.com/questions/11996573/…
stwhite
2
чтобы вернуть нужное значение, нужно просто $ data = $ _GET ['aParam'];
несчастный
Возвращение @ неудачно важно, что вы сэкономили много времени, parse_str () не работал у меня, но $ data = $ _GET ['aParam']; это правильное решение
Асеша Джордж
56

Изменить: не пропустите решение Стефана выше, в котором используется очень удобная http_build_query()функция: https://stackoverflow.com/a/1764199/179125

Knittl прав в отношении побега. Однако есть более простой способ сделать это:

$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 и передачи ключей и значений отдельно. Проверить это.
Jordan Running
но это все равно может превышать максимальный размер параметра GET, верно? каковы шансы, что я буду использовать сеансы вместо упомянутых ниже nash?
uji
Что ж, вы можете хранить более или менее неограниченное количество данных в сеансе. Риск сеансов заключается в том, что URL-адреса ломаются по истечении срока сеанса или если пользователь пытается что-то сделать, например, на двух вкладках одновременно. Если пользователь добавляет страницу в закладки, а затем возвращается по истечении сеанса, получат ли они ожидаемую страницу? Похоже, вам, возможно, нужно больше подумать о своей архитектуре и о том, почему вы вообще передаете такие огромные массивы.
Jordan Running
+1 хороший ответ и работает для меня также после одного года публикации этого ответа.
Naveed
10

Самый простой способ - использовать serializeфункцию.

Он сериализует любую переменную для хранения или передачи. Вы можете прочитать об этом в руководстве по php - сериализация

Переменную можно восстановить, используя unserialize

Итак, при переходе к URL-адресу, который вы используете:

$url = urlencode(serialize($array))

и восстановить используемую вами переменную

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

Но будьте осторожны. Максимальный размер GET-запроса ограничен 4 КБ, который можно легко превысить, передав массивы в URL-адресе.

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

Нэш
источник
сериализация - тоже хороший способ сделать это, но теперь он уже в не очень удобочитаемой форме
knittl
1
Да, сериализация - это не совсем простой способ делать что-то, когда вы работаете с URL-адресами, потому что она сильно расширяет данные. Лучше пойти на кастом.
Kzqai
Максимальный размер параметра GET был тем, что меня беспокоило, поэтому я (глупо) надеялся, что синтаксический анализатор не будет возражать, если это массив, который передается. Я только что понял, что он не будет работать, не коснувшись максимального размера. В любом случае спасибо, Нэш, думаю, я буду делать это с сессиями
удзи
4
Вы действительно не должны передавать ненадежные данные в unserialize (). Попробуйте вместо этого json_encode () и json_decode ().
Микко Ранталайнен 09
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);
}
knittl
источник
1
Вместо того, чтобы использовать «первую» переменную для пропуска первого & amp;, вы можете использовать временный массив для хранения ваших значений и использовать последующие слова implode. Просто для удобства чтения. 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";} и

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'];
user2638158
источник
0

на полученной странице вы можете использовать:

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

CarlosP
источник
Добро пожаловать в Stack Overflow. Добавляя ответ на вопрос десятилетней давности к восьми другим ответам, очень важно указать, какой новый аспект вопроса затрагивает ваш ответ. Прямо сейчас похоже, что у вас есть ответ только на код, который уже был охвачен одним из других ответов. Пожалуйста, используйте форматирование кода для будущих ответов.
Джейсон Аллер,
0

Это еще один способ решения этой проблемы.

$data = array(
              1,
              4,
             'a' => 'b',
             'c' => 'd'
              );
$query = http_build_query(array('aParam' => $data));
Азиама Амос
источник