2012-10-25 70 views
18

使用Symfony2,我需要訪問基於HTTPS的外部API。Symfony2 - 如何執行外部請求

如何調用外部URI並管理響應以「播放」它。例如,要呈現成功或失敗消息?

我想在類似的信息(注意,performRequest完全是一種本發明的方法):

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

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

我一直在閱讀有關Buzz和其他客戶端。但我想Symfony2應該可以自己做。

+0

什麼樣的要求?只需HTTP GET? –

+0

任何GET或POST都很容易知道;) – ElPiter

回答

25

我建議使用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); 

注:您的Web服務器上的PHP必須安裝php5-curl庫。

假設API請求正在返回JSON數據,this page可能會有用。

這不使用任何特定於Symfony2的代碼。很可能有一束可以簡化這個過程,但如果有我不知道它。

+2

只是想說明這個例子包含錯誤地使用了「Content-Type」頭文件。在請求中使用時,它指示正文的類型(在您的示例中未使用)。爲了表明你希望服務器返回什麼類型,你可以使用Accept頭, 'Accept:application/json' header –

24

Symfony沒有爲此提供的內置服務,但這是使用依賴注入框架創建自己的完美機會。你可以在這裏做的是寫一個服務來管理外部呼叫。我們稱之爲服務「http」。

首先,寫一個類有performRequest()方法:

namespace MyBundle\Service; 

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

註冊爲服務app/config/config.yml

services: 
    http: 
     class: MyBundle\Service\Http 

現在你的控制器訪問一個名爲 「HTTP」 服務。 Symfony的管理這個類的一個實例,在「集裝箱」,並且你可以通過$this->get("http")訪問:

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

    ... 
} 
10

https://github.com/sensio/SensioBuzzBundle似乎是你在找什麼。

它實現了Kris Wallsmith buzz庫來執行HTTP請求。

我就讓你讀GitHub的頁面上的文檔,使用是非常基本的:

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

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

echo $response->getContent(); 
3

的Symfony沒有自己的休息客戶,但你已經提到有幾個束。這一個是我的一個者優先:

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

您通過

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

發送請求並得到響應Symfony的對象。 然後你就可以通過

$httpCode = $response-> getStatusCode(); 

獲取狀態碼你的代碼是這樣:

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

最好的客戶是:http://docs.guzzlephp.org/en/latest/

已經有捆綁,它集成到Symfony2的項目: 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'); 

更多信息可以在:http://docs.guzzlephp.org/en/latest/index.html

+0

請注意,Guzzle需要PHP> = 5.5.0,這是symfony要求(v5.3.3):) –

+0

From GuzzleBundle github頁面: 要求PHP 5.4或更高版本但是現在Guzzle lib需要PHP> = 5.5.0。自從我回答以來,我認爲這已經改變了。 –

+0

是的,但這似乎並不是最新的,我只是提出了一個拉式請求來糾正GuzzleBundle存儲庫。我認爲這兩個Guzzle和GuzzleBundle的作者終於會與答案:) +1無論如何,我不知道這個優秀的圖書館,感謝談論它! –