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.

user3379466
quelle
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

Michal Gallovic
quelle
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;
user3379466
quelle
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>';
Frank Roth
quelle
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());
davykiash
quelle
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();
CharlieJade
quelle
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();
Yamen Ashraf
quelle
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

arcos.lwm
quelle
6
use GuzzleHttp\Client;

$client = new Client();

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

Siehe Dokumente .

Nurul Huda
quelle
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());
Tuncay Elvanağaç
quelle
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.

j boschiero
quelle
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']));
Suraj
quelle
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();

quelle
-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('[email protected]', 'password', 'Digest'),)));

$url          = "https://api.yourbaseapiserver.com/incidents.xml";
        
$data = '<incident>
<name>Incident Title2a</name>
<priority>Medium</priority>
<requester><email>[email protected]</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('[email protected]', '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;
Dung
quelle