2012-10-25 11 views
18

Utilizzando Symfony2, ho bisogno di accedere a un'API esterna basata su HTTPS.Symfony2 - Come eseguire una richiesta esterna

Come posso chiamare un URI esterno e gestire la risposta per "riprodurlo" con esso. Ad esempio, per rendere un successo o un messaggio di errore?

Penso in qualcosa di simile (si noti che performRequest è un metodo completamente inventato):

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

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

ho letto su Buzz e altri clienti. Ma immagino che Symfony2 dovrebbe essere in grado di farlo da solo.

+0

Che tipo di richiesta? Solo HTTP GET? –

+0

Qualsiasi GET o POST sarebbe buono a sapersi;) – ElPiter

risposta

25

avrei suggerirei di usare 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); 

Nota: Il php sul vostro server web deve avere la libreria php5-curl installato.

Supponendo che la richiesta API restituisca dati JSON, this page potrebbe essere utile.

Questo non utilizza alcun codice specifico per Symfony2. Potrebbe esserci un pacchetto che può semplificare questo processo per te, ma se c'è non lo so.

+2

Voglio solo notare che l'esempio contiene un uso errato di un'intestazione 'Content-Type'. Se utilizzato in una richiesta, indica il tipo di corpo (che non è utilizzato nell'esempio). Per indicare quale tipo desideri che il server restituisca, utilizzerai un'intestazione 'Accept', ad es. 'Accept: application/json' header –

24

Symfony non ha un servizio integrato per questo, ma questa è un'opportunità perfetta per crearne una propria, utilizzando il framework di dipendenze dell'iniezione. Quello che puoi fare qui è scrivere un servizio per gestire la chiamata esterna. Chiamiamo il servizio "http".

In primo luogo, scrivere una classe con un metodo performRequest():

namespace MyBundle\Service; 

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

registrarlo come servizio in app/config/config.yml:

services: 
    http: 
     class: MyBundle\Service\Http 

Ora il controller ha accesso a un servizio denominato "http". Symfony gestisce una singola istanza di questa classe nel "contenitore", ed è possibile accedervi tramite $this->get("http"):

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

    ... 
} 
10

https://github.com/sensio/SensioBuzzBundle sembra essere quello che stai cercando.

Implementa la libreria buzz di Kris Wallsmith per eseguire richieste HTTP.

Ti farò leggere il doc sulla pagina GitHub, l'utilizzo è piuttosto semplice:

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

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

echo $response->getContent(); 
3

Symfony non dispone di un proprio client di riposo, ma come già accennato ci sono un paio di pacchi. Questo è il mio preferito uno:

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'); 

Si invia la richiesta via

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

e ottenere un oggetto risposta Symfony. allora si può ottenere il codice di stato tramite

$httpCode = $response-> getStatusCode(); 

Il codice sarà simile:

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

miglior cliente che so è: http://docs.guzzlephp.org/en/latest/

c'è già bundle che integra in Symfony2 progetto: 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'); 

Ulteriori informazioni possono essere trovate su: http://docs.guzzlephp.org/en/latest/index.html

+0

Basta notare che Guzzle richiede PHP> = 5.5.0, che è un po 'più recente rispetto ai requisiti di symfony (v5.3.3) :) –

+0

Dalla pagina github di GuzzleBundle: Requisiti PHP 5.4 o superiore ma ora la lib di Guzzle richiede PHP> = 5.5.0. Penso che questo sia cambiato dalla mia risposta. –

+0

Sì, ma questo non sembra aggiornato, ho appena proposto una richiesta di pull per correggerlo sul repository GuzzleBundle. Penso che l'autore di Guzzle e GuzzleBundle finalmente arriverà con la risposta :) +1 in ogni caso, non conoscevo questa eccellente biblioteca, grazie per averne parlato! –

Problemi correlati