【问题标题】:Call a REST API in PHP在 PHP 中调用 REST API
【发布时间】:2022-02-25 08:14:44
【问题描述】:

我们的客户给了我一个 REST API,我需要对其进行 PHP 调用。但实际上API提供的文档非常有限,所以我真的不知道如何调用服务。

我试过用谷歌搜索它,但唯一出现的是一个已经过期的 Yahoo!关于如何调用服务的教程。没有提及标题或任何深入的信息。

关于如何调用 REST API 或相关文档是否有任何体面的信息?因为即使在 W3schools 中,它们也只描述 SOAP 方法。在 PHP 中制作 API 的其余部分有哪些不同的选择?

【问题讨论】:

    标签: php rest web-services


    【解决方案1】:

    您可以使用 PHP cURL 扩展访问任何 REST API。但是,API 文档(方法、参数等)必须由您的客户提供!

    例子:

    // Method: POST, PUT, GET etc
    // Data: array("param" => "value") ==> index.php?param=value
    
    function CallAPI($method, $url, $data = false)
    {
        $curl = curl_init();
    
        switch ($method)
        {
            case "POST":
                curl_setopt($curl, CURLOPT_POST, 1);
    
                if ($data)
                    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
                break;
            case "PUT":
                curl_setopt($curl, CURLOPT_PUT, 1);
                break;
            default:
                if ($data)
                    $url = sprintf("%s?%s", $url, http_build_query($data));
        }
    
        // Optional Authentication:
        curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
        curl_setopt($curl, CURLOPT_USERPWD, "username:password");
    
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    
        $result = curl_exec($curl);
    
        curl_close($curl);
    
        return $result;
    }
    

    【讨论】:

    • @Michiel:HTTP 请求方法(GET、POST、PUT 等)。根据 API,需要不同的方法。即 GET 用于阅读,POST 用于写作。
    • @Michiel $data 是一个关联数组 (data[fieldname] = value),它保存发送到 api 方法的数据。
    • 感谢您的大力协助!
    • 注意,curl_close函数没有被调用,如果反复调用CallAPI函数会导致额外的内存消耗。
    • 下面@colan 的回答要好得多——它为您省去了构建自己的错误处理和包装方法的麻烦。
    【解决方案2】:

    如果你有一个 url 并且你的 php 支持它,你可以调用 file_get_contents:

    $response = file_get_contents('http://example.com/path/to/api/call?param1=5');
    

    如果$response是JSON,使用json_decode转成php数组:

    $response = json_decode($response);
    

    如果 $response 是 XML,使用 simple_xml 类:

    $response = new SimpleXMLElement($response);
    

    http://sg2.php.net/manual/en/simplexml.examples-basic.php

    【讨论】:

    • 如果 REST 端点返回 HTTP 错误状态(例如 401),file_get_contents 函数将失败并返回一个警告并返回 null。如果正文包含错误消息,则无法检索它。
    • 它的主要缺点是您的 PHP 安装必须启用 fopen 包装器才能访问 URL。如果未启用 fopen 包装器,您将无法将 file_get_contents 用于 Web 服务请求。
    • fopen 包装器是现在被视为漏洞的 PHP 部分之一,因此您可能会看到一些主机禁用它。
    【解决方案3】:

    使用Guzzle。这是一个“PHP HTTP 客户端,可以轻松使用 HTTP/1.1 并消除使用 Web 服务的痛苦”。使用 Guzzle 比使用 cURL 容易得多。

    这是来自网站的示例:

    $client = new GuzzleHttp\Client();
    $res = $client->get('https://api.github.com/user', [
        'auth' =>  ['user', 'pass']
    ]);
    echo $res->getStatusCode();           // 200
    echo $res->getHeader('content-type'); // 'application/json; charset=utf8'
    echo $res->getBody();                 // {"type":"User"...'
    var_export($res->json());             // Outputs the JSON decoded data
    

    【讨论】:

    • 仍在使用 cURL 的人从未仔细研究过此选项。
    • 看起来不错。但是获取PNG呢?对于地图图块。我只能在您链接的网页上找到提到的 JSON 数据。
    • @HenrikErlandsson,一个快速的谷歌搜索发现似乎是一个不错的解决方案。 stackoverflow.com/questions/55881436/…
    【解决方案4】:

    CURL 是最简单的方法。这是一个简单的调用

    $ch = curl_init();
    curl_setopt($ch, CURLOPT_URL, "THE URL TO THE SERVICE");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, POST DATA);
    $result = curl_exec($ch);
    
    
    print_r($result);
    curl_close($ch);
    

    【讨论】:

      【解决方案5】:

      使用HTTPFUL

      Httpful 是一个简单的、可链接的、可读的 PHP 库,旨在使 HTTP 变得更理智。它让开发人员专注于与 API 交互,而不是筛选 curl set_opt 页面,是一个理想的 PHP REST 客户端。

      Httpful 包括...

      • 可读的 HTTP 方法支持(GET、PUT、POST、DELETE、HEAD 和 OPTIONS)
      • 自定义标题
      • 自动“智能”解析
      • 自动负载序列化
      • 基本认证
      • 客户端证书验证
      • 请求“模板”

      例如

      发送 GET 请求。获取自动解析的 JSON 响应。

      库注意到响应中的 JSON Content-Type 并自动将响应解析为原生 PHP 对象。

      $uri = "https://www.googleapis.com/freebase/v1/mqlread?query=%7B%22type%22:%22/music/artist%22%2C%22name%22:%22The%20Dead%20Weather%22%2C%22album%22:%5B%5D%7D";
      $response = \Httpful\Request::get($uri)->send();
      
      echo 'The Dead Weather has ' . count($response->body->result->album) . " albums.\n";
      

      【讨论】:

      • 我正在尝试使用 HTTPFUL 作为解决方案,但我不确定它是否可以像 $condition = $response->weather[0]->main; 那样解析 json,除非我只是在 PHP 方面做错了
      【解决方案6】:

      您需要知道您调用的 REST API 是否支持 GETPOST,或同时支持这两种方法。下面的代码对我有用,我正在调用我自己的 Web 服务 API,所以我已经知道 API 需要什么以及它将返回什么。它同时支持GETPOST 方法,因此不太敏感的信息进入URL (GET),用户名和密码等信息作为POST 变量提交。此外,一切都通过HTTPS 连接。

      在 API 代码中,我将一个想要返回的数组编码为 json 格式,然后只需使用 PHP 命令 echo $my_json_variable 即可将该 json 字符串提供给客户端。

      如您所见,我的 API 返回 json 数据,但您需要知道(或查看返回的数据以了解)来自 API 的响应的格式。

      这是我从客户端连接到 API 的方式:

      $processed = FALSE;
      $ERROR_MESSAGE = '';
      
      // ************* Call API:
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL, "http://www.myapi.com/api.php?format=json&action=subscribe&email=" . $email_to_subscribe);
      curl_setopt($ch, CURLOPT_POST, 1);// set post data to true
      curl_setopt($ch, CURLOPT_POSTFIELDS,"username=myname&password=mypass");   // post data
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      $json = curl_exec($ch);
      curl_close ($ch);
      
      // returned json string will look like this: {"code":1,"data":"OK"}
      // "code" may contain an error code and "data" may contain error string instead of "OK"
      $obj = json_decode($json);
      
      if ($obj->{'code'} == '1')
      {
        $processed = TRUE;
      }else{
        $ERROR_MESSAGE = $obj->{'data'};
      }
      
      ...
      
      if (!$processed && $ERROR_MESSAGE != '') {
          echo $ERROR_MESSAGE;
      }
      

      顺便说一句,我也尝试使用这里的一些用户建议的file_get_contents() 方法,但这对我来说效果不佳。我发现curl 方法更快更可靠。

      【讨论】:

        【解决方案7】:

        您可以使用 POSTMAN,这是一个简化 API 的应用程序。 填写请求字段,然后它将为您生成不同语言的代码。 只需点击右侧的代码并选择您喜欢的语言。

        【讨论】:

        • 这是 stackoverflow 上最被低估的答案
        【解决方案8】:

        实际上有很多客户。其中之一是Pest - 看看这个。请记住,这些 REST 调用是具有各种方法的简单 http 请求:GET、POST、PUT 和 DELETE。

        【讨论】:

          【解决方案9】:

          正如@Christoph Winkler 所说,这是实现它的基类:

          curl_helper.php

          // This class has all the necessary code for making API calls thru curl library
          
          class CurlHelper {
          
          // This method will perform an action/method thru HTTP/API calls
          // Parameter description:
          // Method= POST, PUT, GET etc
          // Data= array("param" => "value") ==> index.php?param=value
          public static function perform_http_request($method, $url, $data = false)
          {
              $curl = curl_init();
          
              switch ($method)
              {
                  case "POST":
                      curl_setopt($curl, CURLOPT_POST, 1);
          
                      if ($data)
                          curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
                      break;
                  case "PUT":
                      curl_setopt($curl, CURLOPT_PUT, 1);
                      break;
                  default:
                      if ($data)
                          $url = sprintf("%s?%s", $url, http_build_query($data));
              }
          
              // Optional Authentication:
              //curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
              //curl_setopt($curl, CURLOPT_USERPWD, "username:password");
          
              curl_setopt($curl, CURLOPT_URL, $url);
              curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
          
              $result = curl_exec($curl);
          
              curl_close($curl);
          
              return $result;
          }
          
          }
          

          然后您可以随时包含该文件并使用它,例如:any.php

              require_once("curl_helper.php");
              ...
              $action = "GET";
              $url = "api.server.com/model"
              echo "Trying to reach ...";
              echo $url;
              $parameters = array("param" => "value");
              $result = CurlHelper::perform_http_request($action, $url, $parameters);
              echo print_r($result)
          

          【讨论】:

            【解决方案10】:

            除了函数名所暗示的GET 方法之外,您还可以使用file_get_contents 发出任何http POST/PUT/DELETE/OPTIONS/HEAD 方法。

            How to post data in PHP using file_get_contents?

            【讨论】:

            【解决方案11】:

            如果您使用的是 Symfony,那么有一个很棒的 rest 客户端包,它甚至包括所有 ~100 个异常并抛出它们而不是返回一些无意义的错误代码 + 消息。

            你真的应该检查一下: https://github.com/CircleOfNice/CiRestClientBundle

            我喜欢这个界面:

            try {
                $restClient = new RestClient();
                $response   = $restClient->get('http://www.someUrl.com');
                $statusCode = $response->getStatusCode();
                $content    = $response->getContent();
            } catch(OperationTimedOutException $e) {
                // do something
            }
            

            适用于所有 http 方法。

            【讨论】:

              【解决方案12】:

              如果您愿意使用第三方工具,请查看以下工具: https://github.com/CircleOfNice/DoctrineRestDriver

              这是一种使用 API 的全新方式。

              首先,您定义一个实体,该实体定义传入和传出数据的结构,并使用数据源对其进行注释:

              /*
               * @Entity
               * @DataSource\Select("http://www.myApi.com/products/{id}")
               * @DataSource\Insert("http://www.myApi.com/products")
               * @DataSource\Select("http://www.myApi.com/products/update/{id}")
               * @DataSource\Fetch("http://www.myApi.com/products")
               * @DataSource\Delete("http://www.myApi.com/products/delete/{id}")
               */
              class Product {
                  private $name;
              
                  public function setName($name) {
                      $this->name = $name;
                  }
              
                  public function getName() {
                      return $this->name;
                  }
              }
              

              现在与 REST API 通信非常容易:

              $product = new Product();
              $product->setName('test');
              // sends an API request POST http://www.myApi.com/products ...
              $em->persist($product);
              $em->flush();
              
              $product->setName('newName');
              // sends an API request UPDATE http://www.myApi.com/products/update/1 ...
              $em->flush();
              

              【讨论】:

              • 免责声明:如果这个包你就是作者
              猜你喜欢
              • 1970-01-01
              • 2011-04-12
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多