2008-12-09 31 views
40

Tôi có một ứng dụng PHP đôi khi sẽ phải xử lý các URL có nhiều thông số trong URL sẽ có cùng tên. Có cách nào dễ dàng để lấy tất cả các giá trị cho một khóa nhất định không? PHP $ _GET chỉ trả về giá trị cuối cùng.Cách nhận nhiều tham số có cùng tên từ URL trong PHP

Để làm cho bê tông này, ứng dụng của tôi là một resolver OpenURL, và có thể nhận được các thông số URL như sau:

ctx_ver=Z39.88-2004 
&rft_id=info:oclcnum/1903126 
&rft_id=http://www.biodiversitylibrary.org/bibliography/4323 
&rft_val_fmt=info:ofi/fmt:kev:mtx:book 
&rft.genre=book 
&rft.btitle=At last: a Christmas in the West Indies. 
&rft.place=London, 
&rft.pub=Macmillan and co., 
&rft.aufirst=Charles 
&rft.aulast=Kingsley 
&rft.au=Kingsley, Charles, 
&rft.pages=1-352 
&rft.tpages=352 
&rft.date=1871 

(Vâng, tôi biết đó là xấu xí, chào mừng đến với thế giới của tôi). Lưu ý rằng chìa khóa "rft_id" xuất hiện hai lần:

  1. rft_id=info:oclcnum/1903126
  2. rft_id=http://www.biodiversitylibrary.org/bibliography/4323

$_GET sẽ trở lại chỉ http://www.biodiversitylibrary.org/bibliography/4323, giá trị trước đó (info:oclcnum/1903126) đã được ghi đè.

Tôi muốn có quyền truy cập vào cả hai giá trị. Điều này có thể trong PHP? Nếu không, bất kỳ suy nghĩ về cách xử lý vấn đề này?

Trả lời

63

Cái gì như:

$query = explode('&', $_SERVER['QUERY_STRING']); 
$params = array(); 

foreach($query as $param) 
{ 
    list($name, $value) = explode('=', $param, 2); 
    $params[urldecode($name)][] = urldecode($value); 
} 

mang đến cho bạn:

array(
    'ctx_ver'  => array('Z39.88-2004'), 
    'rft_id'  => array('info:oclcnum/1903126', 'http://www.biodiversitylibrary.org/bibliography/4323'), 
    'rft_val_fmt' => array('info:ofi/fmt:kev:mtx:book'), 
    'rft.genre' => array('book'), 
    'rft.btitle' => array('At last: a Christmas in the West Indies.'), 
    'rft.place' => array('London'), 
    'rft.pub'  => array('Macmillan and co.'), 
    'rft.aufirst' => array('Charles'), 
    'rft.aulast' => array('Kingsley'), 
    'rft.au'  => array('Kingsley, Charles'), 
    'rft.pages' => array('1-352'), 
    'rft.tpages' => array('352'), 
    'rft.date' => array('1871') 
) 
+0

if (! array_key_exists ($ name, $ params)) $ params [$ name] = array(); Là không cần thiết, $ params [$ name] [] = $ value sẽ khởi tạo mảng nếu nó không tồn tại. – Sam

+0

Có cách nào để nhận tất cả các giá trị tham số có tên giống hệt nhau trong trường hợp POST có tải lên tệp không? –

+0

@Mikko: Ý bạn là gì về "tên giống hệt nhau", chính xác? – Tomalak

9

Tôi nghĩ bạn phải phân tích cú pháp $_SERVER['QUERY_STRING'] theo cách thủ công.

Giống như (chưa được kiểm tra):

$query = $_SERVER['QUERY_STRING']; 
$vars = array(); 
foreach (explode('&', $query) as $pair) { 
    list($key, $value) = explode('=', $pair); 
    $vars[] = array(urldecode($key), urldecode($value)); 
} 

này sẽ cho bạn một mảng $vars:

array(
    array('ctx_ver'  => 'Z39.88-2004'), 
    array('rft_id'  => 'info:oclcnum/1903126'), 
    array('rft_id'  => 'http://www.biodiversitylibrary.org/bibliography/4323'), 
    array('rft_val_fmt' => 'info:ofi/fmt:kev:mtx:book'), 
    array('rft.genre' => 'book'), 
    array('rft.btitle' => 'At last: a Christmas in the West Indies.'), 
    array('rft.place' => 'London'), 
    array('rft.pub'  => 'Macmillan and co.'), 
    array('rft.aufirst' => 'Charles'), 
    array('rft.aulast' => 'Kingsley'), 
    array('rft.au'  => 'Kingsley, Charles'), 
    array('rft.pages' => '1-352'), 
    array('rft.tpages' => '352'), 
    array('rft.date' => '1871') 
) 

Sau khi nhìn thấy Tomalak's câu trả lời, tôi thích định dạng dữ liệu của mình cho mảng kết quả tốt hơn nhiều, vì nó làm cho nó có thể truy cập các khóa cụ thể theo tên của chúng.

+0

Thiếu ";" sau dòng thứ hai $ vars = array(); và tôi cần phải bao gồm $ _SERVER ['QUERY_STRING'] trong html_entity_decode để chuyển đổi & thành &, nhưng khi đã hoàn thành, hãy xử lý. Cảm ơn nhiều. – rdmpage

2

AFAIK không có cách nào để có được giá trị nhân bản sử dụng $_GET như giá trị thứ hai sẽ ghi đè lên người đầu tiên

Để khắc phục nó, bạn có thể truy cập vào chuỗi truy vấn liệu sử dụng $_SERVER['QUERY_STRING'] và sau đó phân tích nó cho mình.

37

Sẽ không hoạt động với bạn vì có vẻ như bạn không kiểm soát chuỗi truy vấn, nhưng một câu trả lời hợp lệ khác: Thay vì phân tích chuỗi truy vấn, bạn có thể appeand '[]' vào cuối tên, sau đó PHP sẽ tạo một mảng các mục.

IE:

someurl.php?name[]=aaa&name[]=bbb 

sẽ cung cấp cho bạn một $ _GET trông như:

array(0=>'aaa', 1=>'bbb') 
+0

Đề nghị tốt, tôi sẽ không nghĩ rằng Tôi giả định rằng OP không có quyền truy cập để thay đổi giá trị –

+0

Lưu ý rằng bạn cũng có thể sử dụng số (hoặc thậm chí chuỗi) trong dấu ngoặc để chuyển mảng kết hợp. Vì vậy, nếu bạn không kiểm soát nó, đừng dựa vào nó là 0-indexed. someurl.php? name [5] = aaa & name [zip] = bbb – Andrew

1

Giả bạn có một chuỗi truy vấn như thế này:

param1 = 2549 & appname = appName1 & appname = appName2 & appname = appName3 & appname = appName4 & appname = appName5 & apptype = thetype & idsess = 1231324567980147dzeze55sd4 & hành động = myaction

Bạn có thể thực hiện việc này:

public static function getMultipleParameters() 
    { 
     $query = $_SERVER['QUERY_STRING']; 
     $vars = array(); 
     $second = array(); 
     foreach (explode('&', $query) as $pair) { 
      list($key, $value) = explode('=', $pair); 
      if('' == trim($value)){ 
       continue; 
      } 

      if (array_key_exists($key, $vars)) { 
       if (!array_key_exists($key, $second)) 
        $second[$key][] .= $vars[$key]; 
       $second[$key][] = $value; 
      } else { 
       $vars[$key] = urldecode($value); 
      } 
     } 
     return array_merge($vars, $second); 
    } 

Điều đó mang lại:

array (
    'param1' => '2549', 
    'appname' => 
     array (
     0 => 'appName1', 
     1 => 'appName2', 
     2 => 'appName3', 
     3 => 'appName4', 
     4 => 'appName5', 
), 
    'apptype' => 'thetype', 
    'idsess' => '1231324567980147dzeze55sd4', 
    'action' => 'myaction', 
); 

Hy vọng rằng sẽ giúp;)

1

Chia sẻ phiên bản của tôi về chức năng này

function parse_mstr($query_string,&$query=array()){ 
    $params = explode('&', $query_string); 
    foreach($params as $param){ 
     $k = $param; 
     $v = ''; 
     if(strpos($param,'=')){ 
      list($name, $value) = explode('=', $param); 
      $k = rawurldecode($name); 
      $v = rawurldecode($value); 
     } 
     if(isset($query[$k])){ 
      if(is_array($query[$k])){ 
       $query[$k][] = $v; 
      }else{ 
       $query[$k] = array($query[$k],$v); 
      } 
     }else{ 
      $query[$k] = $v; 
     } 
    } 
} 
4

Không có nhu cầu sử dụng ngu ngốc explode cách giải quyết cho việc này. Một regex đơn giản có thể dễ dàng hơn khắc phục một QUERY_STRING với nhiều thông số như tên:

// Replace `&x=1&x=2` into `x[]=1&x[]=2` 
$qs = preg_replace("/(?<=^|&)(\w+)(?==)/", "$1[]", $_SERVER["QUERY_STRING"]); 

Sau đó, nó đơn giản như sử dụng parse_str:

parse_str($qs, $new_GET); 

nào có lợi thế là giải mã một cách chính xác %xy URL thoát ngay lập tức .

Nếu bạn chỉ muốn một hoặc một vài tham số cụ thể được trích xuất dưới dạng mảng, thì hãy sử dụng (id|name) thay vì (\w+) trong regex.

Các vấn đề liên quan