2012-10-25 12 views
18

Mit Symfony2 muss ich auf eine externe API zugreifen, die auf HTTPS basiert.Symfony2 - So führen Sie eine externe Anforderung aus

Wie kann ich einen externen URI aufrufen und die Antwort verwalten, um damit "zu spielen". Zum Beispiel, um eine Erfolgs- oder eine Fehlermeldung zu rendern?

ich in etwas denke wie (beachten Sie, dass performRequest eine völlig erfundene Verfahren ist):

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

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

Ich habe über Buzz und andere Kunden gelesen. Aber ich denke, dass Symfony2 es selbst schaffen könnte.

+0

Welche Art von Anfrage? Nur HTTP GET? –

+0

Jeder GET oder POST wäre gut zu wissen;) – ElPiter

Antwort

25

Ich würde vorschlagen, ROTATION mit:

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

Hinweis: Die PHP auf Ihrem Webserver die php5-curl Bibliothek installiert haben muss. Wenn die API-Anfrage JSON-Daten zurückgibt, kann this page nützlich sein.

Dies verwendet keinen für Symfony2 spezifischen Code. Es kann durchaus ein Bündel geben, das diesen Prozess für Sie vereinfachen kann, aber wenn ich weiß, weiß ich nichts darüber.

+2

Ich möchte nur darauf hinweisen, dass das Beispiel eine fehlerhafte Verwendung eines Headers "Content-Type" enthält. Wenn es in einer Anfrage verwendet wird, gibt es den Typ des Körpers an (der in Ihrem Beispiel nicht verwendet wird). Um anzugeben, welchen Typ der Server zurückgeben soll, würden Sie einen "Accept" -Header verwenden, z. 'Accept: application/json' header –

24

Symfony hat hierfür keinen integrierten Dienst, aber dies ist eine perfekte Möglichkeit, um Ihre eigenen zu erstellen, indem Sie das Abhängigkeits-Injection-Framework verwenden. Was Sie hier tun können, ist einen Dienst schreiben, um den externen Anruf zu verwalten. Rufen wir den Dienst "http" an.

Erstens eine Klasse mit einer performRequest() Methode schreiben:

namespace MyBundle\Service; 

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

es als Dienst in app/config/config.yml registrieren:

services: 
    http: 
     class: MyBundle\Service\Http 

Jetzt Ihren Controller Zugriff auf einen Dienst namens "http". Symfony verwaltet eine einzelne Instanz dieser Klasse in der „Container“, und Sie können es über $this->get("http") zugreifen:

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

    ... 
} 
10

https://github.com/sensio/SensioBuzzBundle scheint zu sein, was Sie suchen.

Es implementiert die Buzz-Bibliothek von Kris Wallsmith, um HTTP-Anforderungen auszuführen.

Ich werde Ihnen das Dokument auf der GitHub Seite lesen lassen, Nutzung ist ziemlich einfach:

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

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

echo $response->getContent(); 
3

Symfony hat keinen eigenen Rest Client haben, aber wie Sie bereits erwähnt sind ein paar Bündel. Dieses ist mein ein lieber:

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

Sie die Anfrage über

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

und erhalten Objekt eine Symfony Antwort senden. Dann können Sie den Statuscode über

$httpCode = $response-> getStatusCode(); 

Ihr Code erhalten würde wie folgt aussehen:

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

Beste Client, ich weiß, ist: http://docs.guzzlephp.org/en/latest/

Es ist bereits bündeln, dass es in Symfony2 integriert 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'); 

Weitere Informationen finden Sie unter: http://docs.guzzlephp.org/en/latest/index.html

+0

Bitte beachten Sie, dass Guzzle PHP> = 5.5.0 benötigt, was etwas jünger ist als die Symfony-Anforderungen (v5.3.3) :) –

+0

From GuzzleBundle github Seite: Anforderungen PHP 5.4 oder höher aber jetzt benötigen Guzzle lib PHP> = 5.5.0. Ich denke, das hat sich seit meiner Antwort geändert. –

+0

Ja, aber das scheint nicht up-to-date, schlug ich nur eine Pull-Anfrage, um es auf GuzzleBundle Repository zu korrigieren. Ich denke, der Autor von Guzzle und GuzzleBundle wird endlich mit der Antwort kommen :) +1 auf jeden Fall, ich kannte diese ausgezeichnete Bibliothek nicht, vielen Dank für das Gespräch! –

Verwandte Themen