【问题标题】:How can I use Guzzle to send a POST request in JSON?如何使用 Guzzle 以 JSON 格式发送 POST 请求?
【发布时间】:2014-04-10 06:49:32
【问题描述】:

有人知道使用Guzzlepost JSON 的正确方法吗?

$request = $this->client->post(self::URL_REGISTER,array(
                'content-type' => 'application/json'
        ),array(json_encode($_POST)));

我收到来自服务器的internal server error 响应。它可以使用 Chrome Postman

【问题讨论】:

  • 请求似乎没问题...您是否检查过 $_POST 的内容以确保您在编码之前确实获得了这些值? : var_dump($_POST)
  • 现在根据文档,您可以使用@davykiash 所说的,'json' => $data:stackoverflow.com/a/44154428/842768

标签: php postman guzzle


【解决方案1】:

$client->request('POST',...的解决方案...

对于那些使用 $client->request 的人来说,这是创建 JSON 请求的方式:

$client = new Client();
$res = $client->request('POST', "https://some-url.com/api", [
    'json' => [
        'paramaterName' => "parameterValue",
        'paramaterName2' => "parameterValue2",
    ]
    'headers' => [
    'Content-Type' => 'application/json',
    ]
]);

【讨论】:

    【解决方案2】:

    我使用下面的代码,它工作得非常可靠。

    JSON数据传入参数$request,具体请求类型传入变量$searchType。

    代码包含一个陷阱,用于检测和报告不成功或无效的调用,然后返回 false。

    如果调用成功,则 json_decode ($result->getBody(), $return=true) 返回结果数组。

        public function callAPI($request, $searchType) {
        $guzzleClient = new GuzzleHttp\Client(["base_uri" => "https://example.com"]);
    
        try {
            $result = $guzzleClient->post( $searchType, ["json" => $request]);
        } catch (Exception $e) {
            $error = $e->getMessage();
            $error .= '<pre>'.print_r($request, $return=true).'</pre>';
            $error .= 'No returnable data';
            Event::logError(__LINE__, __FILE__, $error);
            return false;
        }
        return json_decode($result->getBody(), $return=true);
    }
    

    【讨论】:

    • 那个json选项超级好用
    【解决方案3】:

    对于 Guzzle :

    这是一个原始的发布请求,因此将 JSON 放入正文中解决了问题

    $request = $this->client->post(
        $url,
        [
            'content-type' => 'application/json'
        ],
    );
    $request->setBody($data); #set body!
    $response = $request->send();
    

    【讨论】:

    • 这不再适用于 GuzzleHttp。 @Charlie 有正确的答案
    • 我想我们只需要在问题中指定 Guzzle 的版本即可。
    • 如果要在 Guzzle 6 中设置内容类型标头,可以这样:$client-&gt;post($url, ['body' =&gt; $string, 'headers' =&gt; ['Content-type' =&gt; 'application/json']]);
    • 我已经用 Guzzle3 尝试过这个方法,即使它是文档中提到的方式,它也不起作用:guzzle3.readthedocs.io/http-client/…,我试图解决这个问题已经 2 天了,但徒劳无功
    • 根据现在的文档,您可以使用@davykiash 所说的,'json' =&gt; $data:stackoverflow.com/a/44154428/842768
    【解决方案4】:

    您可以使用硬编码的json 属性作为键,也可以方便地使用GuzzleHttp\RequestOptions::JSON 常量。

    这里是使用硬编码json字符串的例子。

    use GuzzleHttp\Client;
    
    $client = new Client();
    
    $response = $client->post('url', [
        'json' => ['foo' => 'bar']
    ]);
    

    Docs

    【讨论】:

      【解决方案5】:

      对于 Guzzle 5、6 和 7,您可以这样做:

      use GuzzleHttp\Client;
      
      $client = new Client();
      
      $response = $client->post('url', [
          GuzzleHttp\RequestOptions::JSON => ['foo' => 'bar'] // or 'json' => [...]
      ]);
      

      Docs

      【讨论】:

      • 这是正确的做法 (official example here)
      • 建议对选项数组键使用RequestOptions 常量(在这种情况下为GuzzleHttp\RequestOptions::JSON) - 它使拼写错误更容易被发现,因为它们突然变成了通知,而不仅仅是等待引起麻烦的无声错误.
      • @MichalGallovic 是一样的。使用常量的目的是避免拼写错误。使用不存在的常量会引发错误,但发送无用的选项(例如 jsson)不会引发任何错误,而且您可能需要一些时间才能找到错字。
      • 我为这个答案寻找了一个小时。为什么这不在文档中(尤其是快速设置指南)?疯了!?!
      • @giovannipds GuzzleHttp\RequestOptions::JSON 是 'json' 的别名,两者都可以。
      【解决方案6】:

      PHP 版本:5.6

      Symfony 版本:2.3

      狂饮:5.0

      我最近有一个使用 Guzzle 发送 json 的经验。我使用 Symfony 2.3,所以我的 guzzle 版本可能有点旧。

      我还将展示如何使用调试模式,您可以在发送之前查看请求,

      当我发出如下所示的请求时,得到了成功的响应;

      use GuzzleHttp\Client;
      
      $headers = [
              'Authorization' => 'Bearer ' . $token,        
              'Accept'        => 'application/json',
              "Content-Type"  => "application/json"
          ];        
      
          $body = json_encode($requestBody);
      
          $client = new Client();    
      
          $client->setDefaultOption('headers', $headers);
          $client->setDefaultOption('verify', false);
          $client->setDefaultOption('debug', true);
      
          $response = $client->post($endPoint, array('body'=> $body));
      
          dump($response->getBody()->getContents());
      

      【讨论】:

        【解决方案7】:
        $client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);
        
        $response = $client->post('/save', [
            'json' => [
                'name' => 'John Doe'
            ]
        ]);
        
        return $response->getBody();
        

        【讨论】:

          【解决方案8】:

          只要用这个就行了

             $auth = base64_encode('user:'.config('mailchimp.api_key'));
              //API URL
              $urll = "https://".config('mailchimp.data_center').".api.mailchimp.com/3.0/batches";
              //API authentication Header
              $headers = array(
                  'Accept'     => 'application/json',
                  'Authorization' => 'Basic '.$auth
              );
              $client = new Client();
              $req_Memeber = new Request('POST', $urll, $headers, $userlist);
              // promise
              $promise = $client->sendAsync($req_Memeber)->then(function ($res){
                      echo "Synched";
                  });
                $promise->wait();
          

          【讨论】:

            【解决方案9】:

            这对我有用(使用 Guzzle 6)

            $client = new Client(); 
            $result = $client->post('http://api.example.com', [
                        'json' => [
                            'value_1' => 'number1',
                            'Value_group' =>  
                                         array("value_2" => "number2",
                                                "value_3" => "number3")
                                ]
                            ]);
            
            echo($result->getBody()->getContents());
            

            【讨论】:

              【解决方案10】:

              这适用于 Guzzle 6.2:

              $gClient =  new \GuzzleHttp\Client(['base_uri' => 'www.foo.bar']);
              $res = $gClient->post('ws/endpoint',
                                          array(
                                              'headers'=>array('Content-Type'=>'application/json'),
                                              'json'=>array('someData'=>'xxxxx','moreData'=>'zzzzzzz')
                                              )
                                  );
              

              根据文档 guzzle 执行 json_encode

              【讨论】:

                【解决方案11】:

                以上答案对我不起作用。但这对我来说很好。

                 $client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);
                
                 $request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));
                

                【讨论】:

                  【解决方案12】:

                  简单基本的方式(guzzle6):

                  $client = new Client([
                      'headers' => [ 'Content-Type' => 'application/json' ]
                  ]);
                  
                  $response = $client->post('http://api.com/CheckItOutNow',
                      ['body' => json_encode(
                          [
                              'hello' => 'World'
                          ]
                      )]
                  );
                  

                  为了获得响应状态码和正文的内容,我这样做了:

                  echo '<pre>' . var_export($response->getStatusCode(), true) . '</pre>';
                  echo '<pre>' . var_export($response->getBody()->getContents(), true) . '</pre>';
                  

                  【讨论】:

                  • 这确实是一种简单易行的方法。解决了我关于设置正文和标题的问题。非常感谢
                  • 当接受的答案无效时,此答案对我有效。
                  • 我使用了这个的变体。我自己创建了Client,并将标头添加到$client-&gt;post() 调用中。
                  【解决方案13】:

                  @user3379466 是正确的,但这里我完全重写:

                  -package that you need:
                  
                   "require": {
                      "php"  : ">=5.3.9",
                      "guzzlehttp/guzzle": "^3.8"
                  },
                  
                  -php code (Digest is a type so pick different type if you need to, i have to include api server for authentication in this paragraph, some does not need to authenticate. If you use json you will need to replace any text 'xml' with 'json' and the data below should be a json string too):
                  
                  $client = new Client('https://api.yourbaseapiserver.com/incidents.xml', array('version' => 'v1.3', 'request.options' => array('headers' => array('Accept' => 'application/vnd.yourbaseapiserver.v1.1+xml', 'Content-Type' => 'text/xml'), 'auth' => array('username@gmail.com', 'password', 'Digest'),)));
                  

                  $url          = "https://api.yourbaseapiserver.com/incidents.xml";
                          
                  $data = '<incident>
                  <name>Incident Title2a</name>
                  <priority>Medium</priority>
                  <requester><email>dsss@mail.ca</email></requester>
                  <description>description2a</description>
                  </incident>';
                      $request = $client->post($url, array('content-type' => 'application/xml',));
                  
                      $request->setBody($data); #set body! this is body of request object and not a body field in the header section so don't be confused.
                  
                      $response = $request->send(); #you must do send() method!
                      echo $response->getBody(); #you should see the response body from the server on success
                      die;
                  

                  --- * Guzzle 6 * 的解决方案 --- -您需要的包:

                   "require": {
                      "php"  : ">=5.5.0",
                      "guzzlehttp/guzzle": "~6.0"
                  },
                  
                  $client = new Client([
                                               // Base URI is used with relative requests
                                               'base_uri' => 'https://api.compay.com/',
                                               // You can set any number of default request options.
                                               'timeout'  => 3.0,
                                               'auth'     => array('you@gmail.ca', 'dsfddfdfpassword', 'Digest'),
                                               'headers' => array('Accept'        => 'application/vnd.comay.v1.1+xml',
                                                                  'Content-Type'  => 'text/xml'),
                                           ]);
                  
                  $url = "https://api.compay.com/cases.xml";
                      $data string variable is defined same as above.
                  
                  
                      // Provide the body as a string.
                      $r = $client->request('POST', $url, [
                          'body' => $data
                      ]);
                  
                      echo $r->getBody();
                      die;
                  

                  【讨论】:

                  • 谢谢。无法在其他任何地方为遗留 php5.3 项目找到任何 guzzle3 解决方案,希望看到它的换行符也喜欢你的 guzzle6,因为它可以为我节省很多时间。
                  【解决方案14】:

                  @user3379466 的答案可以通过设置$data 来工作,如下所示:

                  $data = "{'some_key' : 'some_value'}";
                  

                  我们的项目需要的是在 json 字符串内的数组中插入一个变量,我做了如下(以防这对任何人都有帮助):

                  $data = "{\"collection\" : [$existing_variable]}";
                  

                  所以$existing_variable 是,比如说,90210,你得到:

                  echo $data;
                  //{"collection" : [90210]}
                  

                  另外值得注意的是,您可能还想设置'Accept' =&gt; 'application/json',以防您访问的端点关心这种事情。

                  【讨论】:

                  • 请注意...您可以使用json_encode 简化您的$data$data = json_encode(array('collection' =&gt; $existing_variable));
                  【解决方案15】:
                  $client = new \GuzzleHttp\Client();
                  
                  $body['grant_type'] = "client_credentials";
                  $body['client_id'] = $this->client_id;
                  $body['client_secret'] = $this->client_secret;
                  
                  $res = $client->post($url, [ 'body' => json_encode($body) ]);
                  
                  $code = $res->getStatusCode();
                  $result = $res->json();
                  

                  【讨论】:

                  • 这是否也设置了正确的标题?正如迈克尔的回答所提到的,我认为['json' =&gt; $body] 是更好的方法。
                  • $res-&gt;json(); 仅适用于 Guzzle 5.3。它已在 v6 中被删除。
                  • 大卫是正确的。这是因为 PSR-7 的实施。请改用json_decode()
                  • 这在您必须发送标头时不起作用,例如git 的授权令牌。你必须实例化一个 Request 对象并使用 send 或 request 函数
                  猜你喜欢
                  • 2022-02-21
                  • 2012-04-02
                  • 1970-01-01
                  • 1970-01-01
                  • 2020-07-14
                  • 2011-09-07
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多