Як я можу використовувати Guzzle для надсилання запиту на пошту в JSON?


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

Згідно Документах, ви можете просто використовувати то , що @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
Це правильний спосіб ( офіційний приклад тут )
П'єр де ЛЕСПІНАЙ

5
Рекомендується використовувати RequestOptionsконстанти для клавіш масиву параметрів ( GuzzleHttp\RequestOptions::JSONу цьому випадку) - це спрощує виявлення помилок друку, оскільки вони раптом стають повідомленнями, а не просто тихими помилками, які чекають, що спричинить проблеми.
ksadowski

7
@MichalGallovic Це те саме. Мета використання константи - уникнути помилок. Використання константи, якої не існує, призведе до помилки, але надсилання непотрібної опції ( jssonнаприклад,) не призведе до помилок, і вам може знадобитися певний час, щоб знайти друк.
zessx

1
Я годину оглядав цю відповідь. Чому цього немає в документації (особливо в посібнику з швидкого налаштування)? Божевільний!?!
Севенеарти

1
@giovannipds GuzzleHttp \ RequestOptions :: JSON - псевдонім 'json', або це добре.
Міхал Галлович

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 у питанні.
Фабрис Кабонго

1
Якщо ви хочете встановити заголовок типу вмісту в Guzzle 6, ви можете зробити це так:$client->post($url, ['body' => $string, 'headers' => ['Content-type' => 'application/json']]);
marcovtwout

Я спробував це з Guzzle3 не працює, навіть якщо це так, як згадується в документі: guzzle3.readthedocs.io/http-client/… , минуло 2 дні, я намагаюся вирішити цю програму, але даремно
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
Це дійсно один простий і простий спосіб. Вирішили мою проблему щодо налаштування тіла та заголовків. Дуже дякую
Файсал Сарфраз

Ця відповідь працює для мене, коли прийнята відповідь не відповідає.
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.
Девід

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



2

Php Версія: 5.6

Версія Symfony: 2.3

Гугл: 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, хотілося б, щоб це було безперервно, як і ваша guzzle6, так як це врятувало б мені багато часу.
тавр

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();
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.