Related
Does anybody know the correct way to post JSON using Guzzle?
$request = $this->client->post(self::URL_REGISTER,array(
'content-type' => 'application/json'
),array(json_encode($_POST)));
I get an internal server error response from the server. It works using Chrome Postman.
For Guzzle 5, 6 and 7 you do it like this:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
GuzzleHttp\RequestOptions::JSON => ['foo' => 'bar'] // or 'json' => [...]
]);
Docs
The simple and basic way (guzzle6):
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->post('http://api.com/CheckItOutNow',
['body' => json_encode(
[
'hello' => 'World'
]
)]
);
To get the response status code and the content of the body I did this:
echo '<pre>' . var_export($response->getStatusCode(), true) . '</pre>';
echo '<pre>' . var_export($response->getBody()->getContents(), true) . '</pre>';
For Guzzle <= 4:
It's a raw post request so putting the JSON in the body solved the problem
$request = $this->client->post(
$url,
[
'content-type' => 'application/json'
],
);
$request->setBody($data); #set body!
$response = $request->send();
This worked for me (using 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());
$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();
You can either using hardcoded json attribute as key, or you can conveniently using GuzzleHttp\RequestOptions::JSON constant.
Here is the example of using hardcoded json string.
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
'json' => ['foo' => 'bar']
]);
See Docs.
$client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);
$response = $client->post('/save', [
'json' => [
'name' => 'John Doe'
]
]);
return $response->getBody();
This works for me with 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')
)
);
According to the documentation guzzle do the json_encode
Solution for $client->request('POST',...
For those who are using $client->request this is how you create a JSON request:
$client = new Client();
$res = $client->request('POST', "https://some-url.com/api", [
'json' => [
'paramaterName' => "parameterValue",
'paramaterName2' => "parameterValue2",
]
'headers' => [
'Content-Type' => 'application/json',
]
]);
Guzzle JSON Request Reference
Php Version: 5.6
Symfony version: 2.3
Guzzle: 5.0
I had an experience recently about sending json with Guzzle. I use Symfony 2.3 so my guzzle version can be a little older.
I will also show how to use debug mode and you can see the request before sending it,
When i made the request as shown below got the successfull response;
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());
#user3379466 is correct, but here I rewrite in full:
-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;
--- Solution for * Guzzle 6 * ---
-package that you need:
"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;
Simply use this it will work
$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();
I use the following code that works very reliably.
The JSON data is passed in the parameter $request, and the specific request type passed in the variable $searchType.
The code includes a trap to detect and report an unsuccessful or invalid call which will then return false.
If the call is sucessful then json_decode ($result->getBody(), $return=true) returns an array of the results.
public function callAPI($request, $searchType) {
$guzzleClient = new GuzzleHttp\Client(["base_uri" => "https://example.com"]);
try {
$result = $guzzleClient->post( $searchType, ["json" => $request]);
} catch (Exception $e) {
$error = $e->getMessage();
$error .= '<pre>'.print_r($request, $return=true).'</pre>';
$error .= 'No returnable data';
Event::logError(__LINE__, __FILE__, $error);
return false;
}
return json_decode($result->getBody(), $return=true);
}
The answer from #user3379466 can be made to work by setting $data as follows:
$data = "{'some_key' : 'some_value'}";
What our project needed was to insert a variable into an array inside the json string, which I did as follows (in case this helps anyone):
$data = "{\"collection\" : [$existing_variable]}";
So with $existing_variable being, say, 90210, you get:
echo $data;
//{"collection" : [90210]}
Also worth noting is that you might want to also set the 'Accept' => 'application/json' as well in case the endpoint you're hitting cares about that kind of thing.
Above answers did not worked for me somehow. But this works fine for me.
$client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);
$request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));
I have this code to send whatsapp API
<?php
require_once('vendor/autoload.php');
$client = new \GuzzleHttp\Client();
$product="shadow";
$response = $client->request('POST', 'https://live-server-10100.wati.io/api/v1/sendTemplateMessage?whatsappNumber=96655642XXXXX',
[
'body' => '{"parameters":
[{"name":"name1","value":"hosam"},
{"name":"discount_code","value":"gh5"},
{"name":"shop_name","value":$product}],
"template_name":"aband_cart4",
"broadcast_name":"test01"}',
'headers' => [
'Authorization' => 'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJqdGkiOiI0OTFmOGNkOS1mOWNOTM5Yy04MTEzMzhmMzc1ZjEiLCJ1bmlxdWVfbmFtZSI6ImFkbWluQGdoYW5hdHkuY29tIiwibmFtZWlkIjoiYWRtaW5AZ2hhbmF0eS5jb20iLCJlbWFpbCI6ImFkbWluQGdoYW5hdHkuY29tIiwiYXV0aF90aW1lIjoiMDIvMDUvMjAyMyAwNDo1NzozOCIsImRiX25hbWUiOiIxMDE3MDAiLCJodHRwOi8vc2NoZW1hcy5taWNyb3NvZnQuY29tL3dzLzIwMDgvMDYvaWRlbnRpdHkvY2xhaW1zL3JvbGUiOiJBRE1JTklTVFJBVE9SIiwiZXhwIjoyNTM0MDIzMDA4MDAsImlzcyI6IkNsYXJlX0FJIiwiYXVkIjoiQ2xhcmVfQUkifQ.3scVLBYDnzxPWlGQ_UfUgR_ecFQgnahQCnRQkAuzjoY',
'content-type' => 'text/json',
],
]);
echo $response->getBody();
?>
I tried to send post code with user value, and get error:
"{"result":false,"info":"Parameters is incorrect""
So what is the way to add PHP value $product to JSON?
I tried to convert an AJAX API request script into php using Guzzle, however I keep getting a '400 Bad Request' error. The Ajax version works fine.But I'm trying to automate the process in the back end. The script sends a file to the remote API via a 'POST' request and is meant to return a JSON object back which I then save it to a file.
Most of the possible solutions I found(googled for) involved either doing some exception handling or straight deactivating the guzzle errors. None of which worked. I know that the credentials are all correct because I tested with wrong credentials and it returned an authorization error.
This AJAX code works fine, it gets a file from an html form and uploads it to the API server.
$('#btnUploadFile').on('click', function () {
var data = new FormData();
var files = $("#fileUpload").get(0).files;
for (var i = 0; i < files.length; i++) {
data.append("audioFiles", files[i]); }
data.append("scoresTypes", JSON.stringify([46, 47]));
data.append("Flavor", 1);
data.append("AgentUsername", 'person#email.com');
var ajaxRequest = $.ajax({ type: "POST", url: 'https://remoteserver.com/api/',
headers: { 'Authorization': 'Basic ' + btoa('username' + ':' + 'password') },
scoresTypes: "",
contentType: false,
processData: false,
data: data,
success: function (data) { $("#response").html(JSON.stringify(data)); } });
ajaxRequest.done(function (xhr, textStatus) { });
});
});
This is the PHP code that returns the error '400 Bad Request' to the file
public function sendFile($file_path, $file_name){
$client = new Client();
$url = 'https://remoteserver.com/api/';
$credentials = base64_encode('username:password');
$audio = fopen($file_path, 'r');
$data = [];
$data['audioFiles'] = $audio;
$data['scoresTypes'] = json_encode([46, 47]);
$data['Flavor'] = 1;
$data['AgentUsername'] = 'person#email.com';
$json_file = '/path/'.$file_name.'.json';
try{
$response = $client->request('POST', $url, [
'headers' => [
'Authorization' => 'Basic '.$credentials,
],
'scoresTypes' => '',
'contentType' => 'false',
'processData' => false,
'data'=>$data
]);
$response_s = json_encode($response);
}
catch(RequestException $e) {
$response_s = $e->getResponse()->getBody();
}
Storage::disk('disk_name')->put($json_file, $response_s);
So this is the output that the PHP function is saving to the file instead of the expected JSON object.
{"code":14,"message":"There are no values in scoresTypes or JobTypes keys, please insert valid values in one, or both of them.","responseStatusCode":400}
But as you can see the initial data provided to the ajax version seems to be the same as the one I send in the php request.
have you tried setting the Content-Type to multipart/form-data since you are sending files, i think the default header for post request is application/x-www-form-urlencoded
I'm not a guzzle expert but from what i saw on the examples here you can use something like this instead
http://docs.guzzlephp.org/en/latest/quickstart.html?highlight=file#sending-form-files
<?php
$response = $client->request('POST', 'http://httpbin.org/post', [
'multipart' => [
[
'name' => 'field_name',
'contents' => 'abc'
],
[
'name' => 'file_name',
'contents' => fopen('/path/to/file', 'r')
],
[
'name' => 'other_file',
'contents' => 'hello',
'filename' => 'filename.txt',
'headers' => [
'X-Foo' => 'this is an extra header to include'
]
]
]
]);
I'm using the Azure OCR Service to get the text of an image back (
https://learn.microsoft.com/de-de/azure/cognitive-services/Computer-vision/QuickStarts/PHP).
So far everything is up and running, but now I would like to use a local file instead of an already uploaded one.
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_POST);
// Request body
$request->setBody("{body}"); // Replace with the body, for example, "{"url": "http://www.example.com/images/image.jpg"}
Unfortunately I don't know how to pass the raw binary as the body of my POST request in PHP.
At first, when we refer local file, we should use 'Content-Type': 'application/octet-stream' in a header, then we can send requests that use a stream resource as the body.
Here's my working code using Guzzle for your reference:
<?php
require 'vendor/autoload.php';
$resource = fopen('./Shaki_waterfall.jpg', 'r');
$client = new \GuzzleHttp\Client();
$res = $client->request('POST', 'https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze', [
'query' => [
'visualFeatures' => 'Categories',
'details' => '',
'language' => 'en'
],
'headers' => [
'Content-Type' => 'application/octet-stream',
'Ocp-Apim-Subscription-Key' => '<Ocp-Apim-Subscription-Key>'
],
'body' => $resource
]);
echo $res->getBody();
Using HTTP_Request2:
<?php
require_once 'HTTP/Request2.php';
$request = new Http_Request2('https://westus.api.cognitive.microsoft.com/vision/v1.0/analyze');
$url = $request->getUrl();
$headers = array(
'Content-Type' => 'application/octet-stream',
'Ocp-Apim-Subscription-Key' => '<Ocp-Apim-Subscription-Key>',
);
$request->setHeader($headers);
$parameters = array(
'visualFeatures' => 'Categories',
'details' => '',
'language' => 'en',
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_POST);
$request->setBody(fopen('./Shaki_waterfall.jpg', 'r'));
try {
$response = $request->send();
echo $response->getBody();
} catch (HttpException $ex) {
echo $ex;
}
Does anybody know the correct way to post JSON using Guzzle?
$request = $this->client->post(self::URL_REGISTER,array(
'content-type' => 'application/json'
),array(json_encode($_POST)));
I get an internal server error response from the server. It works using Chrome Postman.
For Guzzle 5, 6 and 7 you do it like this:
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
GuzzleHttp\RequestOptions::JSON => ['foo' => 'bar'] // or 'json' => [...]
]);
Docs
The simple and basic way (guzzle6):
$client = new Client([
'headers' => [ 'Content-Type' => 'application/json' ]
]);
$response = $client->post('http://api.com/CheckItOutNow',
['body' => json_encode(
[
'hello' => 'World'
]
)]
);
To get the response status code and the content of the body I did this:
echo '<pre>' . var_export($response->getStatusCode(), true) . '</pre>';
echo '<pre>' . var_export($response->getBody()->getContents(), true) . '</pre>';
For Guzzle <= 4:
It's a raw post request so putting the JSON in the body solved the problem
$request = $this->client->post(
$url,
[
'content-type' => 'application/json'
],
);
$request->setBody($data); #set body!
$response = $request->send();
This worked for me (using 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());
$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();
You can either using hardcoded json attribute as key, or you can conveniently using GuzzleHttp\RequestOptions::JSON constant.
Here is the example of using hardcoded json string.
use GuzzleHttp\Client;
$client = new Client();
$response = $client->post('url', [
'json' => ['foo' => 'bar']
]);
See Docs.
$client = new \GuzzleHttp\Client(['base_uri' => 'http://example.com/api']);
$response = $client->post('/save', [
'json' => [
'name' => 'John Doe'
]
]);
return $response->getBody();
This works for me with 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')
)
);
According to the documentation guzzle do the json_encode
Solution for $client->request('POST',...
For those who are using $client->request this is how you create a JSON request:
$client = new Client();
$res = $client->request('POST', "https://some-url.com/api", [
'json' => [
'paramaterName' => "parameterValue",
'paramaterName2' => "parameterValue2",
]
'headers' => [
'Content-Type' => 'application/json',
]
]);
Guzzle JSON Request Reference
Php Version: 5.6
Symfony version: 2.3
Guzzle: 5.0
I had an experience recently about sending json with Guzzle. I use Symfony 2.3 so my guzzle version can be a little older.
I will also show how to use debug mode and you can see the request before sending it,
When i made the request as shown below got the successfull response;
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());
#user3379466 is correct, but here I rewrite in full:
-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;
--- Solution for * Guzzle 6 * ---
-package that you need:
"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;
Simply use this it will work
$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();
I use the following code that works very reliably.
The JSON data is passed in the parameter $request, and the specific request type passed in the variable $searchType.
The code includes a trap to detect and report an unsuccessful or invalid call which will then return false.
If the call is sucessful then json_decode ($result->getBody(), $return=true) returns an array of the results.
public function callAPI($request, $searchType) {
$guzzleClient = new GuzzleHttp\Client(["base_uri" => "https://example.com"]);
try {
$result = $guzzleClient->post( $searchType, ["json" => $request]);
} catch (Exception $e) {
$error = $e->getMessage();
$error .= '<pre>'.print_r($request, $return=true).'</pre>';
$error .= 'No returnable data';
Event::logError(__LINE__, __FILE__, $error);
return false;
}
return json_decode($result->getBody(), $return=true);
}
The answer from #user3379466 can be made to work by setting $data as follows:
$data = "{'some_key' : 'some_value'}";
What our project needed was to insert a variable into an array inside the json string, which I did as follows (in case this helps anyone):
$data = "{\"collection\" : [$existing_variable]}";
So with $existing_variable being, say, 90210, you get:
echo $data;
//{"collection" : [90210]}
Also worth noting is that you might want to also set the 'Accept' => 'application/json' as well in case the endpoint you're hitting cares about that kind of thing.
Above answers did not worked for me somehow. But this works fine for me.
$client = new Client('' . $appUrl['scheme'] . '://' . $appUrl['host'] . '' . $appUrl['path']);
$request = $client->post($base_url, array('content-type' => 'application/json'), json_encode($appUrl['query']));