2012-10-25 14 views
18

Korzystając z Symfony2, muszę uzyskać dostęp do zewnętrznego interfejsu API opartego na protokole HTTPS.Symfony2 - Jak wykonać zewnętrzne żądanie?

W jaki sposób można połączyć się z zewnętrznym identyfikatorem URI i zarządzać odpowiedzią, aby go "odtworzyć". Na przykład, aby wyświetlić komunikat o powodzeniu lub niepowodzeniu?

Mam na myśli coś podobnego (zauważ, że performRequest jest całkowicie wymyślona metoda):

$response = $this -> performRequest("www.someapi.com?param1=A&param2=B"); 

if ($response -> getError() == 0){ 
    // Do something good 
}else{ 
    // Do something too bad 
} 

Czytałem o Buzz i innych klientów. Ale myślę, że Symfony2 powinien móc to zrobić samodzielnie.

+0

Jakiego rodzaju prośba? Po prostu HTTP GET? –

+0

Każdy GET lub POST byłoby dobrze wiedzieć;) – ElPiter

Odpowiedz

25

Sugeruję użyciu CURL:

$ch = curl_init(); 
curl_setopt($ch, CURLOPT_URL, 'www.someapi.com?param1=A&param2=B'); 
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json')); // Assuming you're requesting JSON 
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); 

$response = curl_exec($ch); 

// If using JSON... 
$data = json_decode($response); 

Uwaga: php na serwerze WWW muszą mieć zainstalowane biblioteki php5-curl.

Zakładając, że żądanie API zwraca dane JSON, przydatne może być this page.

Nie używa żadnego kodu, który jest specyficzny dla Symfony2. Może istnieć pakiet, który może uprościć ten proces dla ciebie, ale jeśli nie mam o tym pojęcia.

+2

Po prostu chciałbym zauważyć, że przykład zawiera błędne użycie nagłówka 'Content-Type'. W przypadku użycia w żądaniu wskazuje rodzaj ciała (który nie jest używany w twoim przykładzie). Aby wskazać typ, który chcesz zwrócić serwerowi, użyj nagłówka 'Accept', np. 'Zaakceptuj: application/json' header –

24

Symfony nie ma wbudowanej usługi, ale jest to idealna okazja do stworzenia własnego, korzystając ze struktury wtrysku zależności. Tutaj możesz napisać usługę zarządzania połączeniem zewnętrznym. Nazwijmy usługę "http".

Najpierw napisać klasę z metodą performRequest():

namespace MyBundle\Service; 

class Http 
{  
    public function performRequest($siteUrl) 
    { 
     // Code to make the external request goes here 
     // ...probably using cUrl 
    } 
} 

zarejestrować go jako usługa w app/config/config.yml:

services: 
    http: 
     class: MyBundle\Service\Http 

Teraz kontroler ma dostęp do usługi o nazwie "http". Symfony zarządza jedno wystąpienie tej klasy w „kontenerze”, można uzyskać do niego dostęp za pośrednictwem $this->get("http"):

class MyController 
{ 
    $response = $this->get("http")->performRequest("www.something.com"); 

    ... 
} 
10

https://github.com/sensio/SensioBuzzBundle wydaje się być to, czego szukasz.

Implementuje bibliotekę buzzów Kris Wallsmith do wykonywania żądań HTTP.

dam przeczytać doc na stronie github, wykorzystanie jest dość prosty:

$buzz = $this->container->get('buzz'); 

$response = $buzz->get('http://google.com'); 

echo $response->getContent(); 
3

Symfony nie posiada własnego klienta odpoczynek, ale jak już wspomniano, istnieje kilka wiązek. Ten jest mój preferowany jeden:

https://github.com/CircleOfNice/CiRestClientBundle

$restClient = $this->container->get('ci.restclient'); 

$restClient->get('http://www.someUrl.com'); 
$restClient->post('http://www.someUrl.com', 'somePayload'); 
$restClient->put('http://www.someUrl.com', 'somePayload'); 
$restClient->delete('http://www.someUrl.com'); 
$restClient->patch('http://www.someUrl.com', 'somePayload'); 

$restClient->head('http://www.someUrl.com'); 
$restClient->options('http://www.someUrl.com', 'somePayload'); 
$restClient->trace('http://www.someUrl.com'); 
$restClient->connect('http://www.someUrl.com'); 

wysłać żądanie poprzez

$response = $restclient->get($url); 

i uzyskać obiekt odpowiedzi Symfony. Następnie można uzyskać kod stanu poprzez

$httpCode = $response-> getStatusCode(); 

Twój kod będzie wyglądać następująco:

$restClient = $this->container->get('ci.restclient'); 
if ($restClient->get('http://www.yourUrl.com')->getStatusCode !== 200) { 
    // no error 
} else { 
    // error 
} 
12

Najlepszy klient, że wiem to: http://docs.guzzlephp.org/en/latest/

istnieje już pakiet, który integruje je w Symfony2 projekt: https://github.com/8p/GuzzleBundle

$client = $this->get('guzzle.client'); 

// send an asynchronous request. 
$request = $client->createRequest('GET', 'http://httpbin.org', ['future' => true]); 
// callback 
$client->send($request)->then(function ($response) { 
    echo 'I completed! ' . $response; 
}); 

// optional parameters 
$response = $client->get('http://httpbin.org/get', [ 
    'headers' => ['X-Foo-Header' => 'value'], 
    'query' => ['foo' => 'bar'] 
]); 
$code = $response->getStatusCode(); 
$body = $response->getBody(); 

// json response 
$response = $client->get('http://httpbin.org/get'); 
$json = $response->json(); 

// extra methods 
$response = $client->delete('http://httpbin.org/delete'); 
$response = $client->head('http://httpbin.org/get'); 
$response = $client->options('http://httpbin.org/get'); 
$response = $client->patch('http://httpbin.org/patch'); 
$response = $client->post('http://httpbin.org/post'); 
$response = $client->put('http://httpbin.org/put'); 

Więcej informacji można znaleźć na stronie: http://docs.guzzlephp.org/en/latest/index.html

+0

Pamiętaj, że Guzzle wymaga PHP> = 5.5.0, co jest nieco nowszym, niż wymagania symfony (v5.3.3) :) –

+0

Z GuithleBundle strona github: Wymagania PHP 5.4 lub nowszy ale teraz biblioteka Guzzle wymaga PHP> = 5.5.0. Myślę, że to się zmieniło od czasu mojej odpowiedzi. –

+0

Tak, ale to nie wydaje się być aktualne, właśnie zaproponowałem żądanie pullowania, aby poprawić je w repozytorium GuzzleBundle. Myślę, że autor zarówno Guzzle, jak i GuzzleBundle w końcu przyjdzie z odpowiedzią :) +1 tak czy inaczej, nie znałem tej doskonałej biblioteki, dziękuję za rozmowę o tym! –

Powiązane problemy