ฉันจะใช้ Guzzle เพื่อส่งคำขอ POST ใน JSON ได้อย่างไร


180

มีใครรู้วิธีที่ถูกต้องในการpostใช้ JSON Guzzleหรือไม่

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

ฉันได้รับการinternal server errorตอบกลับจากเซิร์ฟเวอร์ มันทำงานใช้ PostmanChrome


คำขอดูเหมือนว่าโอเค ... คุณได้ตรวจสอบเนื้อหาของ $ _POST แล้วเพื่อให้แน่ใจว่าคุณได้รับค่าจริง ๆ ก่อนที่จะเข้ารหัสพวกเขา? : var_dump ($ _ POST)
ylerjen

ตามเอกสารตอนนี้คุณสามารถใช้สิ่งที่ @davykiash พูดว่า'json' => $data:: stackoverflow.com/a/44154428/842768
giovannipds

คำตอบ:


262

สำหรับGuzzle 5, 6 และ 7คุณทำเช่นนี้:

use GuzzleHttp\Client;

$client = new Client();

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

เอกสาร


13
นี่เป็นวิธีที่เหมาะสมในการทำ ( ตัวอย่างเป็นทางการที่นี่ )
Pierre de LESPINAY

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 อีกต่อไป @Charlie มีคำตอบที่ถูกต้อง
hbt

ฉันคิดว่าเราแค่ต้องระบุเวอร์ชันของ Guzzle ในคำถาม
Fabrice Kabongo

1
หากคุณต้องการตั้งค่าส่วนหัวประเภทเนื้อหาใน Guzzle 6 คุณสามารถทำได้เช่นนี้:$client->post($url, ['body' => $string, 'headers' => ['Content-type' => 'application/json']]);
marcovtwout

ฉันได้ลองกับ Guzzle3 ไม่ทำงานแม้ว่ามันจะเป็นวิธีที่กล่าวถึงใน doc: guzzle3.readthedocs.io/http-client/ ...... เป็นเวลา 2 วันที่ฉันพยายามแก้ไข pb นี้ แต่ไร้ประโยชน์
Hanane

ตามเอกสารตอนนี้คุณสามารถใช้สิ่งที่ @davykiash พูดว่า'json' => $data:: stackoverflow.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

คำตอบนี้ใช้ได้สำหรับฉันเมื่อคำตอบที่ยอมรับไม่ได้
vietnguyen09

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]เป็นวิธีที่ดีกว่าที่นี่ตามคำตอบของไมเคิล
Ja͢ck

1
$res->json();ใช้งานได้เฉพาะใน Guzzle 5.3 มันถูกลบออกใน v6
David

1
เดวิดถูกต้อง นี่เป็นเพราะการใช้งาน PSR-7 ใช้json_decode()แทน
Andreas

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

ตามเอกสารคู่มือ guzzle ทำ json_encode



2

รุ่น Php: 5.6

เวอร์ชัน Symfony: 2.3

Guzzle: 5.0

เมื่อเร็ว ๆ นี้ฉันมีประสบการณ์เกี่ยวกับการส่ง json กับ Guzzle ฉันใช้ 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());

0

คำตอบจาก @ user3379466 สามารถทำงานได้โดยการตั้งค่า$dataดังนี้:

$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

@ 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;

ขอบคุณ. ไม่พบโซลูชัน guzzle3 ใด ๆ ที่อื่นสำหรับโครงการ php5.3 แบบดั้งเดิมต้องการดู line-break ต้องการ guzzle6 ของคุณเช่นกันเพราะจะช่วยให้ฉันประหยัดเวลาได้มาก
taur

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();
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.