如何使用Guzzle以JSON发送POST请求?


180

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

$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)
ylerjen 2014年

现在,根据文档,您可以使用@davykiash所说的内容'json' => $datastackoverflow.com/a/44154428/842768
giovannipds

Answers:


261

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

use GuzzleHttp\Client;

$client = new Client();

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

文件


13
这是正确的做法(此处官方示例
Pierre de LESPINAY 2015年

5
建议对RequestOptions选项数组键使用常量(GuzzleHttp\RequestOptions::JSON在这种情况下)-当输入错误突然变成通知时,它使错别字更容易检测,而不仅仅是等待引起麻烦的静默错误。
ksadowski

7
@MichalGallovic也是一样。使用该常数的目的是避免输入错误。使用不存在的常量会引发错误,但是发送无用的选项(jsson例如)不会引发任何错误,并且您可能需要花费一些时间来查找错字。
zessx

1
我正在寻找一个小时的答案。为什么文档(特别是快速安装指南)中没有此内容?疯!?!
Sevenearths,

1
@giovannipds GuzzleHttp \ RequestOptions :: JSON是'json'的别名,也可以。
Michal Gallovic

44

对于Guzzle <= 4

这是原始的发布请求,因此将JSON放入正文即可解决问题

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

return $response;

8
这不再适用于GuzzleHttp。@查理有正确的答案
hbt 2015年

我认为我们只需要在问题中指定Guzzle的版本即可。
Fabrice Kabongo

如果要在Guzzle 6中设置内容类型标头,可以这样进行: $client->post($url, ['body' => $string, 'headers' => ['Content-type' => 'application/json']]);
marcovtwout

我已经尝试过使用Guzzle3进行此操作,即使它在文档中提到的方式也是如此:guzzle3.readthedocs.io/http-client/… ,已经有2天的时间我试图解决此问题,但徒劳无功
Hanane

现在,根据文档,您可以使用@davykiash所说的内容, 'json' => $datastackoverflow.com/a/44154428/842768
giovannipds

42

简单而基本的方法(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>';

2
这确实是一种简单的方法。解决了有关设置正文和标题的问题。非常感谢
Faisal Sarfraz

当接受的答案无效时,此答案对我有用。
vietnguyen19

32

这对我有用(使用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());

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

2
这还会设置正确的标题吗?['json' => $body]正如迈克尔的回答所提到的,我认为这是更好的方法。
杰克

1
$res->json();仅在Guzzle 5.3中有效。在v6中已将其删除。
大卫,

1
大卫是正确的。这是因为实施了PSR-7。使用json_decode()代替。
安德烈亚斯

10
$client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);

$response = $client->post('/save', [
    'json' => [
        'name' => 'John Doe'
    ]
]);

return $response->getBody();

8

这适用于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')
                                )
                    );

根据文档的枪口做json_encode


7
use GuzzleHttp\Client;

$client = new Client();

$response = $client->post('url', [
    'json' => ['foo' => 'bar']
]);

参见文档


2

PHP版本:5.6

Symfony版本:2.3

狂饮:5.0

我最近有过用Guzzle发送json的经验。我使用Symfony 2.3,所以我的耗时版本可能会老一些。

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

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

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

0

通过设置$data如下,可以使@ user3379466的答案起作用:

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

我们的项目需要的是在json字符串内的数组中插入一个变量,我这样做如下(以防万一)

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

因此$existing_variable,假设存在90210,您将获得:

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

另外值得注意的是,如果您要访问'Accept' => 'application/json'的端点关心这种事情,您可能还需要设置。


请注意...您可以$data使用json_encode以下方法简化操作:$data = json_encode(array('collection' => $existing_variable));
phpisuber01

0

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

 $client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);

 $request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));

0

只需使用它就可以了

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

-1

@ 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;
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.