Come posso usare Guzzle per inviare una richiesta POST in JSON?


180

Qualcuno conosce il modo corretto di postutilizzare JSON Guzzle?

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

Ricevo una internal server errorrisposta dal server. Funziona con Chrome Postman.


La richiesta sembra ok ... hai controllato il contenuto di $ _POST per essere sicuro di ottenere davvero i valori prima di codificarli? : var_dump ($ _ POST)
ylerjen

Secondo documenti ora, si può semplicemente utilizzare ciò che @davykiash detto, 'json' => $data: stackoverflow.com/a/44154428/842768
giovannipds

Risposte:


262

Per Guzzle 5 e 6 lo fai in questo modo:

use GuzzleHttp\Client;

$client = new Client();

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

Documenti


13
Questo è il modo giusto di fare ( esempio ufficiale qui )
Pierre de LESPINAY,

5
Si consiglia di utilizzare le RequestOptionscostanti per le chiavi dell'array di opzioni ( GuzzleHttp\RequestOptions::JSONin questo caso): semplifica il rilevamento di errori di battitura poiché diventano improvvisamente notifiche anziché solo bug silenziosi in attesa di causare problemi.
ksadowski,

7
@MichalGallovic È lo stesso. Lo scopo di usare la costante è evitare errori di battitura. L'uso di una costante che non esiste genererà un errore, ma l'invio di un'opzione inutile (come jssonad esempio) non genererà alcun errore e potresti impiegare del tempo per trovare il tuo errore di battitura.
zessx,

1
Stavo cercando un'ora per questa risposta. Perché questo non è nella documentazione (in particolare la guida di installazione rapida)? Pazzo!?!
Sevenearths,

1
@giovannipds GuzzleHttp \ RequestOptions :: JSON è un alias di 'json', o va bene lo stesso.
Michal Gallovic

44

Per Guzzle <= 4 :

Si tratta di una richiesta post non elaborata, pertanto l'inserimento di JSON nel corpo ha risolto il problema

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

return $response;

8
Questo non funziona più con GuzzleHttp. @Charlie ha la risposta giusta
hbt

Penso che dobbiamo solo specificare la versione di Guzzle nella domanda.
Fabrice Kabongo,

1
Se vuoi impostare l'intestazione del tipo di contenuto in Guzzle 6, puoi farlo in questo modo:$client->post($url, ['body' => $string, 'headers' => ['Content-type' => 'application/json']]);
marcovtwout

Ho provato questo con Guzzle3 non funziona anche se è il modo menzionato nel documento: guzzle3.readthedocs.io/http-client/… , sono 2 giorni che sto cercando di risolvere questo pb ma invano
Hanane,

Secondo documenti ora, si può semplicemente utilizzare ciò che @davykiash detto, 'json' => $data: stackoverflow.com/a/44154428/842768
giovannipds

42

Il modo semplice e di base (guzzle6):

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

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

Per ottenere il codice di stato della risposta e il contenuto del corpo ho fatto questo:

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

2
Questo è davvero un modo semplice e facile. Risolto il mio problema con l'impostazione del corpo e delle intestazioni. Grazie mille
Faisal Sarfraz,

Questa risposta funziona per me quando la risposta accettata no.
vietnguyen09,

32

Questo ha funzionato per me (usando 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
Questo imposta anche l'intestazione corretta? Penso che ['json' => $body]sia il modo migliore qui, come menzionato dalla risposta di Michael.
Ja͢ck,

1
$res->json();funziona solo con Guzzle 5.3. È stato rimosso in v6.
David

1
David ha ragione. Ciò è dovuto all'implementazione di PSR-7. Usa json_decode()invece.
Andreas,

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

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

return $response->getBody();

8

Questo funziona per me con 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')
                                )
                    );

Secondo la documentazione guzzle, eseguire json_encode


7
use GuzzleHttp\Client;

$client = new Client();

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

Vedi Documenti .


2

Versione Php: 5.6

Versione di symfony: 2.3

Guzzle: 5.0

Di recente ho avuto un'esperienza sull'invio di JSON con Guzzle. Uso Symfony 2.3, quindi la mia versione di guzzle può essere un po 'più vecchia.

Mostrerò anche come utilizzare la modalità debug e puoi vedere la richiesta prima di inviarla,

Quando ho fatto la richiesta, come mostrato di seguito, ho ottenuto la risposta corretta;

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

La risposta di @ user3379466 può essere fatta funzionare impostando $datacome segue:

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

Ciò di cui il nostro progetto aveva bisogno era inserire una variabile in un array all'interno della stringa json, cosa che ho fatto come segue (nel caso questo aiuti qualcuno):

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

Quindi, con l' $existing_variableessere, diciamo, 90210, ottieni:

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

Vale anche la pena notare che potresti voler impostare 'Accept' => 'application/json'anche nel caso in cui l'endpoint che stai colpendo si preoccupi di quel tipo di cose.


Solo un $datajson_encode$data = json_encode(array('collection' => $existing_variable));
avvertimento

0

@ user3379466 è corretto, ma qui riscrivo per intero:

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

--- Soluzione per * Guzzle 6 * --- -pacchetto di cui hai bisogno:

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

Grazie. Non sono riuscito a trovare alcuna soluzione guzzle3 da nessun'altra parte per i progetti php5.3 legacy, mi piacerebbe vederlo interrompere come il tuo guzzle6, dal momento che mi avrebbe risparmiato un sacco di tempo.
taur

0

Le risposte sopra non hanno funzionato per me in qualche modo. Ma questo funziona bene per me.

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

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

0

Basta usare questo funzionerà

   $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();
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.