Wie kann ich Guzzle verwenden, um eine POST-Anfrage in JSON zu senden?


179

Kennt jemand den richtigen Weg zur postVerwendung von JSON Guzzle?

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

Ich erhalte eine internal server errorAntwort vom Server. Es funktioniert mit Chrome Postman.


Die Anfrage scheint in Ordnung zu sein ... haben Sie den Inhalt von $ _POST überprüft, um sicherzustellen, dass Sie die Werte wirklich erhalten, bevor Sie sie codieren? : var_dump ($ _ POST)
ylerjen

Laut Docs können Sie jetzt einfach das verwenden, was @davykiash gesagt hat 'json' => $data: stackoverflow.com/a/44154428/842768
giovannipds

Antworten:


260

Für Guzzle 5 & 6 machen Sie es so:

use GuzzleHttp\Client;

$client = new Client();

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

Docs


13
Dies ist der richtige Weg ( offizielles Beispiel hier )
Pierre de LESPINAY

5
Es wird empfohlen, RequestOptionsKonstanten für die Options-Array-Schlüssel zu verwenden ( GuzzleHttp\RequestOptions::JSONin diesem Fall). Dadurch lassen sich Tippfehler leichter erkennen, da sie plötzlich zu Benachrichtigungen werden, anstatt nur stille Fehler, die darauf warten, Probleme zu verursachen.
Ksadowski

7
@ MichaelGallovic Es ist das gleiche. Der Zweck der Verwendung der Konstante besteht darin, Tippfehler zu vermeiden. Die Verwendung einer nicht vorhandenen Konstante führt zu einem Fehler, das Senden einer nutzlosen Option (wie jssonz. B.) führt jedoch nicht zu einem Fehler, und es kann einige Zeit dauern, bis Sie Ihren Tippfehler gefunden haben.
Zessx

1
Ich habe mich eine Stunde lang nach dieser Antwort umgesehen. Warum steht dies nicht in der Dokumentation (insbesondere in der Kurzanleitung zur Einrichtung)? Verrückt!?!
Sevenearths

1
@giovannipds GuzzleHttp \ RequestOptions :: JSON ist ein Alias ​​für 'json', beides ist in Ordnung.
Michal Gallovic

45

Für Guzzle <= 4 :

Es ist eine rohe Post-Anfrage, also hat das Einfügen des JSON in den Body das Problem gelöst

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

return $response;

8
Dies funktioniert nicht mehr mit GuzzleHttp. @ Charlie hat die richtige Antwort
hbt

Ich denke, wir müssen nur die Version von Guzzle in der Frage angeben.
Fabrice Kabongo

Wenn Sie den Inhaltstyp-Header in Guzzle 6 festlegen möchten, können Sie dies folgendermaßen tun:$client->post($url, ['body' => $string, 'headers' => ['Content-type' => 'application/json']]);
marcovtwout

Ich habe versucht, dies mit Guzzle3 zu tun, funktioniert nicht, auch wenn es die im Dokument erwähnte Art ist: guzzle3.readthedocs.io/http-client/… , es sind 2 Tage vergangen , ich versuche, dieses
Problem

Laut Docs können Sie jetzt einfach das verwenden, was @davykiash gesagt hat 'json' => $data: stackoverflow.com/a/44154428/842768
giovannipds

42

Der einfache und einfache Weg (guzzle6):

$client = new Client([
    'headers' => [ 'Content-Type' => 'application/json' ]
]);

$response = $client->post('http://api.com/CheckItOutNow',
    ['body' => json_encode(
        [
            'hello' => 'World'
        ]
    )]
);

Um den Antwortstatuscode und den Inhalt des Körpers zu erhalten, habe ich Folgendes getan:

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

2
Dies ist wirklich ein einfacher und einfacher Weg. Mein Problem beim Setzen von Body und Headern wurde gelöst. Vielen Dank
Faisal Sarfraz

Diese Antwort funktioniert bei mir, wenn die akzeptierte Antwort nicht funktioniert.
vietnguyen09

32

Dies funktionierte bei mir (mit 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
Setzt dies auch den richtigen Header? Ich denke, das ['json' => $body]ist der bessere Weg, wie in Michaels Antwort erwähnt.
Ja͢ck

1
$res->json();funktioniert nur in Guzzle 5.3. Es wurde in Version 6 entfernt.
David

1
David ist richtig. Dies liegt an der Implementierung von PSR-7. Verwenden Sie json_decode()stattdessen.
Andreas

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

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

return $response->getBody();

8

Dies funktioniert bei mir mit 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')
                                )
                    );

Laut Dokumentation fressen Sie den json_encode


6
use GuzzleHttp\Client;

$client = new Client();

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

Siehe Dokumente .


2

PHP-Version: 5.6

Symfony-Version: 2.3

Guzzle: 5.0

Ich hatte kürzlich eine Erfahrung mit dem Senden von JSON mit Guzzle. Ich benutze Symfony 2.3, damit meine Guzzle-Version etwas älter sein kann.

Ich werde auch zeigen, wie man den Debug-Modus verwendet, und Sie können die Anfrage sehen, bevor Sie sie senden.

Als ich die Anfrage wie unten gezeigt machte, bekam ich die erfolgreiche Antwort;

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

Die Antwort von @ user3379466 kann $datawie folgt funktionieren :

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

Was unser Projekt brauchte, war das Einfügen einer Variablen in ein Array innerhalb der JSON-Zeichenfolge, was ich wie folgt tat (falls dies jemandem hilft):

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

Also mit zu $existing_variablesein, sagen wir, 90210, erhalten Sie:

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

Erwähnenswert ist auch, dass Sie möglicherweise auch das festlegen möchten, 'Accept' => 'application/json'falls der Endpunkt, den Sie treffen, sich um solche Dinge kümmert.


Nur ein Kopf hoch ... Sie können Ihre vereinfachen, $dataindem Sie json_encode:$data = json_encode(array('collection' => $existing_variable));
phpisuber01

0

Die obigen Antworten haben bei mir irgendwie nicht funktioniert. Aber das funktioniert gut für mich.

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

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

0

Verwenden Sie dies einfach, es wird funktionieren

   $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 ist korrekt, aber hier schreibe ich vollständig um:

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

--- Lösung für * Guzzle 6 * --- -Paket, das Sie benötigen:

 "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;
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.