Truyền mảng dưới dạng tham số url


115

Cách tốt nhất để tôi có thể vượt qua một mảng dưới dạng tham số url là gì? Tôi đã suy nghĩ nếu điều này là có thể:

$aValues = array();

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

hoặc làm thế nào về điều này:

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

Tôi đã đọc các ví dụ, nhưng tôi thấy nó lộn xộn:

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

2
Tại sao bạn không thể đi qua $_POST?
ngẫu nhiên

Điều này thực sự trông lộn xộn. Nhưng đối với cách tiếp cận đó nó phải được. Cách tiếp cận khác, ít phức tạp là chỉ định query = array('aParam'=> json_encode($arrayOfValues)). Và bạn có thể vượt qua trong url đẹp hơn với url_encode(implode('/',$query)). Url sẽ như thế nào www.example.com/aParam/[va1,val2,...]. Khi nhận được bạn phải json_decode giá trị aParam thành mảng.
Vladimir Vukanac

Câu trả lời:


219

Có một giải pháp rất đơn giản : http_build_query(). Nó nhận các tham số truy vấn của bạn như là một mảng kết hợp:

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

sẽ trở lại

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

http_build_query()xử lý tất cả các lối thoát cần thiết cho bạn ( %5B=> [%5D=> ]), vì vậy chuỗi này bằng aParam[0]=1&aParam[1]=4&aParam[a]=b&aParam[c]=d.


16
Nếu bạn đang tự hỏi làm thế nào để đưa điều này trở lại vào một mảng, câu trả lời là parse_str () .
Typo

1
Tôi đã sử dụng điều này để đặt url trong mảng nhưng không biết làm thế nào để lấy lại dữ liệu. Tôi đã thử parse_str và không thể làm cho nó hoạt động. Tôi nghĩ rằng đây sẽ là thông tin có giá trị
Thomas Williams

2
Đối với bất cứ ai gặp vấn đề với việc http_build_querytrở lại param[]và đôi khi param[index]. Kiểm tra bài đăng này: stackoverflow.com/questions/11996573/ từ
stwhite 23/07/17

2
để lấy lại giá trị bạn chỉ cần $ data = $ _GET ['aParam'];
dfortun

@dfortun lấy lại là điều quan trọng, bạn đã tiết kiệm rất nhiều thời gian parse_str () không hoạt động với tôi nhưng $ data = $ _GET ['aParam']; là giải pháp chính xác
Asesha George

56

Chỉnh sửa: Đừng bỏ lỡ giải pháp của Stefan ở trên, sử dụng rất tiện dụnghttp_build_query() chức năng : https://stackoverflow.com/a/1764199/179125

knittl là đúng về việc trốn thoát. Tuy nhiên, có một cách đơn giản hơn để làm điều này:

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

Nếu bạn muốn làm điều này với một mảng kết hợp, thay vào đó hãy thử điều này:

PHP 5.3+ (chức năng 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 (gọi lại)

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
khéo léo! cũng sẽ tốt nếu nó có thể làm việc với các mảng kết hợp. +1 dù sao
knittl

3
knittl: Chúng ta có thể làm điều đó với hàm gọi lại cho Array_map và chuyển các khóa và giá trị riêng biệt. Kiểm tra nó ra.
Jordan Chạy

nhưng điều này vẫn có thể vượt quá kích thước tối đa của tham số GET phải không? tỷ lệ cược là gì nếu tôi sử dụng phiên thay vì giống như nash được đề cập dưới đây?
uji

Chà, bạn có thể lưu trữ một lượng dữ liệu không giới hạn ít nhiều không giới hạn trong một phiên. Rủi ro với các phiên là do URL bị phá vỡ khi phiên hết hạn hoặc nếu người dùng cố gắng thực hiện mọi việc, ví dụ như trong hai tab cùng một lúc. Nếu người dùng đánh dấu trang, sau đó quay lại sau khi phiên của họ hết hạn, liệu họ có còn nhận được trang họ mong đợi không? Có vẻ như bạn có thể cần phải suy nghĩ nhiều hơn về kiến ​​trúc của mình và tại sao bạn lại đi qua các mảng lớn như vậy ngay từ đầu.
Jordan Chạy

+1 câu trả lời tốt và làm việc cho tôi cũng sau một năm đăng câu trả lời này.
Naveed

10

Cách dễ nhất sẽ là sử dụng serializechức năng.

Nó tuần tự hóa bất kỳ biến nào để lưu trữ hoặc chuyển. Bạn có thể đọc về nó trong hướng dẫn sử dụng php - serialization

Biến có thể được khôi phục bằng cách sử dụng unserialize

Vì vậy, trong việc chuyển đến URL bạn sử dụng:

$url = urlencode(serialize($array))

và để khôi phục biến bạn sử dụng

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

Hãy cẩn thận ở đây mặc dù. Kích thước tối đa của yêu cầu GET được giới hạn ở mức 4k, bạn có thể dễ dàng vượt quá bằng cách chuyển các mảng trong một URL.

Ngoài ra, nó thực sự không phải là cách an toàn nhất để truyền dữ liệu! Bạn có lẽ nên xem xét sử dụng phiên thay thế.



1
Vâng, tuần tự hóa không thực sự là một cách làm việc sạch sẽ khi bạn làm việc với các url, bởi vì nó mở rộng dữ liệu rất nhiều. Tốt hơn để đi tùy chỉnh.
Kzqai

kích thước tối đa của tham số GET là điều tôi lo lắng về lý do tại sao tôi (ngu ngốc) hy vọng rằng trình phân tích cú pháp sẽ không phiền nếu đó là một mảng được thông qua. tôi nhận ra rằng nó sẽ không hoạt động mà không chạm vào kích thước tối đa. Dù sao cũng cảm ơn nash, tôi nghĩ rằng tôi sẽ thực hiện nó với các phiên
uji

4
Bạn thực sự không nên chuyển dữ liệu không đáng tin cậy sang unserialize (). Thay vào đó, hãy thử json_encode () và json_decode ().
Mikko Rantalainen

6

vui lòng thoát các biến của bạn khi xuất ( urlencode).

và bạn không thể chỉ in một mảng, bạn phải xây dựng url của mình bằng cách sử dụng một vòng lặp theo một cách nào đó

$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
Thay vì sử dụng biến "đầu tiên" để bỏ qua & amp;, bạn có thể sử dụng một mảng tạm thời để lưu trữ các giá trị của mình và sử dụng mật khẩu ẩn. Chỉ để dễ đọc. 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"; cho 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"; cho

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

Vì vậy, nếu bạn muốn chuyển cái này $arrayqua URL tới page_no_2.php,

Ví dụ:-

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

Để trở về mảng ban đầu, nó cần phải được urldecode(), sau đó unserialize(), như thế này trong page_no_2.php:

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

cho

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

một lần nữa: D



1

Đây không phải là câu trả lời trực tiếp vì điều này đã được trả lời, nhưng mọi người đều nói về việc gửi dữ liệu, nhưng không ai thực sự nói bạn làm gì khi đến đó, và tôi đã mất nửa giờ để xử lý nó. Vì vậy, tôi nghĩ rằng tôi sẽ giúp đỡ ở đây.

Tôi sẽ lặp lại điều này

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

Rõ ràng bạn sẽ định dạng nó tốt hơn www.someurl.com?x=$query này

Và để lấy lại dữ liệu

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

trong trang nhận được, bạn có thể sử dụng:

parse_str ($ str, $ mảng); var_dump (mảng $);


Chào mừng bạn đến với Stack Overflow. Khi thêm câu trả lời cho câu hỏi mười năm tuổi với tám câu trả lời khác, điều rất quan trọng là chỉ ra khía cạnh mới của câu hỏi mà câu trả lời của bạn giải quyết. Ngay bây giờ có vẻ như bạn chỉ có một câu trả lời mã đã được bao phủ bởi một trong những câu trả lời khác. Vui lòng sử dụng định dạng mã cho mã trong các câu trả lời trong tương lai.
Jason Aller
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.