【问题标题】:Symfony2 - How to perform an external RequestSymfony2 - 如何执行外部请求
【发布时间】:2020-04-14 19:06:42
【问题描述】:

使用 Symfony2,我需要访问一个基于 HTTPS 的外部 API。

如何调用外部 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应该可以自己做。

【问题讨论】:

  • 什么样的要求?只是 HTTP GET?
  • 任何 GET 或 POST 都会很高兴知道 ;)

标签: php http symfony


【解决方案1】:

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

注意:您的网络服务器上的 php 必须安装 php5-curl 库。

假设 API 请求返回 JSON 数据,this page 可能有用。

这不使用任何特定于 Symfony2 的代码。很可能有一个捆绑包可以为您简化此过程,但如果有的话我不知道。

【讨论】:

  • 只是想注意该示例包含错误使用 Content-Type 标头。在请求中使用时,它指示正文的类型(在您的示例中未使用)。要指示您希望服务器返回什么类型,您可以使用 Accept 标头,例如Accept: application/json标头
【解决方案2】:

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

    ...
}

【讨论】:

    【解决方案3】:

    我认识的最好的客户是: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

    【讨论】:

    • 请注意,Guzzle 需要 PHP >= 5.5.0,这比 symfony 要求 (v5.3.3) 更新一些 :)
    • 来自 GuzzleBundle github 页面:要求 PHP 5.4 或更高版本,但现在 Guzzle lib 需要 PHP >= 5.5.0。我认为自从我的回答以来这已经改变了。
    • 是的,但这似乎不是最新的,我只是在 GuzzleBundle 存储库中提出了一个拉取请求来更正它。我认为 Guzzle 和 GuzzleBundle 的作者最终都会给出答案 :) +1 反正我不知道这个优秀的库,谢谢你的谈论!
    • 没问题。我再次检查了它,最新版本的 GuzzleBundle 正在使用需要 PHP 5.4 的 Guzzle 5.3:guzzle.readthedocs.org/en/5.3/overview.html#requirements。 Guzzle 6.0 需要 PHP 5.5。
    • 是的,实际上是在写评论后才注意到的。然而,作者正在寻找 GuzzleBundle 是否可以支持 Guzzle v6。所以它可能很快就会改变,但我现在说话有点太快了。打扰了!
    【解决方案4】:

    https://github.com/sensio/SensioBuzzBundle 似乎就是您要找的东西。

    它实现了 Kris Wallsmith 嗡嗡声库来执行 HTTP 请求。

    我会让你阅读github页面上的文档,用法很基本:

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

    【讨论】:

      【解决方案5】:

      Symfony 没有自己的 rest 客户端,但正如您已经提到的,有几个捆绑包。这是我最喜欢的一个:

      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
      }
      

      【讨论】:

        【解决方案6】:

        使用 HttpClient 类创建发出请求的低级 HTTP 客户端,如以下 GET 请求:

            use Symfony\Component\HttpClient\HttpClient;
        
        $client = HttpClient::create();
        $response = $client->request('GET', 'https://api.github.com/repos/symfony/symfony-docs');
        
        $statusCode = $response->getStatusCode();
        // $statusCode = 200
        $contentType = $response->getHeaders()['content-type'][0];
        // $contentType = 'application/json'
        $content = $response->getContent();
        // $content = '{"id":521583, "name":"symfony-docs", ...}'
        $content = $response->toArray();
        // $content = ['id' => 521583, 'name' => 'symfony-docs', ...]
        

        这与 Symfony 5 兼容。有关此主题的 Symfony 手册:The HttpClient Component

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2022-08-19
          • 2016-04-03
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多