2013-06-18 20 views
5

Chcę skonstruować ten adres URL przy użyciu http_build_query:PHP http_build_query z dwoma kluczami tablicy, które są takie same

https://www.googleapis.com/freebase/v1/topic/m/0d6lp?filter=/common/topic/notable_for&filter=/common/topic/alias 

Należy pamiętać, że „filter =” pochodzi dwukrotnie parametr w adresie URL, aby określić dwa filtry.

starałem się zrobić to w ten sposób, ale problem:

$service_url = 'https://www.googleapis.com/freebase/v1/topic'; 
$mid = '/m/0d6lp'; 
$params = array('filter' => '/common/topic/notable_for', 'filter' => '/common/topic/alias'); 
$url = $service_url . $mid . '?' . http_build_query($params); 

Problemem jest to, jak „filtr” array kluczowe powtarza dwa razy, tylko ostatni parametr pojawia się w http_build_query. Jak utworzyć oryginalny adres URL z dwoma filtrami?

+0

Możliwy duplikat [http \ _build \ _query z tymi samymi parametrami nazwa] (http://stackoverflow.com/questions/8170306/http-build-query-with-same-name-parameters) –

Odpowiedz

0
  1. Nie można zapisać w tablicy accoc dwóch lub więcej wartości z jednym indeksem.
  2. Api nie przyjmować wartości jak filter[]

tak, to proponujemy, aby utworzyć własną funkcję do zbudowania danego zapytania.

+0

Interfejs API obsługuje wiele filtrów. Możesz uruchomić adres URL podany w przeglądarce i zobaczyć, że oba filtry mają zastosowanie. Jest to również wspomniane w dokumentacji API. – Ninja

+0

@Ninja, usunięto z odpowiedzi. – sectus

6

Problem polega oczywiście na tym, że każdy klucz w tablicy PHP (hash) może mieć tylko jedną wartość. Zasadniczo, skrót PHP nie jest dobrym odwzorowaniem kwerendy, ponieważ łańcuch zapytania ma kolejność i nie ma żadnych ograniczeń co do unikalności kluczy.

Aby temu zapobiec, trzeba specjalny wypełniacz ciągu kwerendy, które mogą obsługiwać zduplikowane klucze:

class QueryString { 
    private $parts = array(); 

    public function add($key, $value) { 
     $this->parts[] = array(
      'key' => $key, 
      'value' => $value 
     ); 
    } 

    public function build($separator = '&', $equals = '=') { 
     $queryString = array(); 

     foreach($this->parts as $part) { 
      $queryString[] = urlencode($part['key']) . $equals . urlencode($part['value']); 
     } 

     return implode($separator, $queryString); 
    } 

    public function __toString() { 
     return $this->build(); 
    } 
} 

Przykład użycia (Codepad Demo):

$qs = new QueryString(); 
$qs->add('filter', '1'); 
$qs->add('filter', '2'); 
var_dump($qs->build()); // filter=1&filter=2 
+0

Ale kiedy będzie dostępny za pośrednictwem '$ _GET ['filter']' zwróci '2', a nie' 1 & 2'. Musisz użyć 2 różnych kluczy tutaj. –

+2

@YogeshSuthar To dlatego, że $ _GET jest hash (i nie może dokładnie reprezentować kwerendy). Kiedy PHP parsuje QS, nadpisuje duplikaty. Jeśli przeanalizujesz kwerendę z duplikatami kluczy (z 'php: // input' dla POST lub' $ _SERVER ['QUERY_STRING'] 'dla GET) możesz wyodrębnić dwie wartości. Weź również pod uwagę klucze takie jak "filter []", które PHP agreguje do tablicy.Querystrings pozwalają na wielokrotne ustawianie klawiszy. –

+1

@YogeshSuthar Sprawdź również, w jaki sposób [Java go obsługuje] (http://docs.oracle.com/javaee/6/api/javax/servlet/ServletRequest.html#getParameterValues ​​(java.lang.String)) zwraca tablicę wartości dla każdego klucza. [To pytanie SO] (http://stackoverflow.com/questions/1746507/authoritative-position-of-duplicate-http-get-query-keys) również potwierdza, że ​​jest to ustalony (choć nie udokumentowany) standard umożliwiający klucze do przypisania wielu wartości. –

0

nie jest najlepszym rozwiązaniem, ale mam obejście:

$item = [ 
    'key1' => array('value1','value2'), 
    'key2' => array('value3','value4') 
]; 

$array=[ 
    'aaa' => 'aaa', 
    'null' => 'null&'.preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', http_build_query($item,null,'&')), 
    'zzz' => 'zzz' 
]; 

echo urldecode(http_build_query($array)); 

wyjściowa:

aaa aaa & = NULL = null & klucz1 = wartość1 & klucz1 = value2 & klucz2 = wartość3 & klucz2 = value4 & zzz = zzz

UWAGA: prawdopodobnie nie będzie działać przyczyną url będą:

= aaa aaa & Brak = NULL% 26key1% 3Dvalue1% 26key1% 3Dvalue2% 26key2% 3Dvalue3% 26key2% 3Dvalue4 & zzz = zzz

EDIT: Inną opcją będzie preg wynik przed przypisać go do URL:

preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '=', http_build_query($item)) 

wyjściowa:

klucz1 = wartość1 & klucz1 = value2 & klucz2 = value3 & key2 = value4

0

Mam rozszerzoną odpowiedź @Baileya Parkera, aby obsłużyć ciąg parametrów parametrów przekazanych za pomocą znaku []. Kod ten tworzy ciąg kwerendy gdzie jeden klucz ma wiele wartości

class QueryString 
{ 
     private $parts = array(); 

     public function add($key, $value) { 
       if(empty($value))return; 
       if(is_array($value)) 
       { 
         foreach ($value as $v) 
           $this->add($key,$v); 
       } 
       else 
       { 
         $this->parts[$key][] = $value; 
       } 

     } 

     public function build($separator = '&', $equals = '=') { 
       $queryString = array(); 

       $parts = array(); 
       foreach($this->parts as $key=>$value) 
       { 
         if(count($value) > 1) 
           $parts[$key] = $value; 
         else 
           $parts[$key] = $value[0]; 
       } 
       $query = http_build_query($parts); 
       return preg_replace('/%5B(?:[0-9]|[1-9][0-9]+)%5D=/', '[]=', $query);; 

     } 

     public function __toString() { 
       return $this->build(); 
     } 

} 

kod ten można również zaakceptować tablicę wartości dla określonego klucza

$qs = new QueryString(); 
$qs->add('trialId', array('1','2')); 
$qs->add('packageId', '12'); 
$qs->add('frequencyId', '4'); 
var_dump($qs->build()); 

tej klasy będzie produkować normalny ciąg kwerendy, z kluczem posiadające wiele wartości dodanych z [] znak, wyjście będzie jak tego

?frequencyId=4&packageId=12&trialId[]=1&trialId[]=2 
Powiązane problemy