I have a little php api client with this method:
private function send($endpoint)
{
$headers = array();
$body = $this->xmlSerialiser->convertToXML($this->getQueue());
try {
$response = json_decode(
$this->guzzleClient->post(
$endpoint,
$headers, $body
)
->send()
->json()
);
} catch (\Guzzle\Http\Exception\BadResponseException $e) {
$response = array('Error' => $e->getMessage());
}
return $response;
}
I'm always receiving
Unable to parse response body into JSON: 4 (500 Internal Server Error)
I already tried to know an example of server response and seems to be fine:
echo (string) $this->guzzleClient->post(
$endpoint,
$headers, $body
)
->send()->getBody();
and this is the result:
<Messages xmlns="http://www.example.com/xxx/3.0">
<GetAccountResponse RequestType="GetAccount">
<AccountId>xxxx-xxx-xxx-xxxx-xxxx</AccountId>
<Token>xxxxxxxxxxxxxx/t3VkEJXC7f6b6G4yPJSZ5QfT2hdSQXUmi0e8cndSYLK4N7mswRHifzwGHLUJYHM17iGL8s=</Token>
</GetAccountResponse>
I answered myself
the Guzzle documentation says: json method -> Parse the JSON response body and return an array
so in my case I need to switch the json mehod to xml (cos the response is an xml).
Finally this is the result:
private function send($endpoint)
{
$headers = array();
$body = $this->xmlSerialiser->convertToXML($this->getQueue());
try {
$response = (array)(
$this->guzzleClient->post(
$endpoint,
$headers, $body
)
->send()
->xml()
);
} catch (\Guzzle\Http\Exception\BadResponseException $e) {
$response = array('Error' => $e->getMessage());
}
return $response;
}
Use following code.
$response->getBody()->getContents()
Related
I am using laravel guzzle package for get response from this https://eos.greymass.com/v1/history/get_transaction url
$client = new Client();
try {
$response = $client->request('GET', 'https://eos.greymass.com/v1/history/get_transaction?id=18a20dbc34082451143c03ac54a2f24d06494d51e68f8fb1211ca0b63a53f37d');
}catch (ClientException $e) {
$response = $e->getResponse();
$responseBodyAsString = $response->getBody()->getContents();
return redirect()->back()->with('error', $responseBodyAsString);
}
if ($response->getStatusCode() != 200){
return redirect()->back()->with('error', 'Status code must be 200');
}
$body = $response->getBody();
return $body;
I get $body data properly, but when i tried to get $body->block_num then showing me this Undefined property: GuzzleHttp\Psr7\Stream::$block_num error
You have to decode the $response to get it as because it will convert json into an object
So for example:
$response = json_decode($client->request('GET', 'https://eos.greymass.com/v1/history/get_transaction?id=18a20dbc34082451143c03ac54a2f24d06494d51e68f8fb1211ca0b63a53f37d')->getBody(), true);
Try This! It will Help You
I am sending a POST request to an API, Curl returns 200 and the correct response.
When Implementing with GuzzleHttp\Client, I get a 400 Bad request, what is wrong with my formatting.
here is my code using Laravel Returns 400 Bad Request:
$client = new Client();
$URI = 'http://api.example.com';
$params['headers'] = ['Content-Type' => 'application/json',
'apikey' => config('app._api_key'),
'debug' => true
];
$params['form_params'] = [
'sender' => 'Test_sender',
'recipient' => config('app.test_recipient'),
'message_body' => 'Test body'
];
return $response = $client->post($URI, $params);
Curl (Returns 200):
curl -X POST --header 'Content-Type: application/json' --header 'Accept: application/json' --header 'apikey: 212121212’ -d '{ "message_body": "test","sender": "2018","recipient": “4453424141” }' 'http://api.example.com'
Try the below code:
$client = new \GuzzleHttp\Client(['headers' => ['Content-Type' => 'application/json',
'apikey'=> config('app._api_key'),
'debug' => true
]
]);
$URI = 'http://api.example.com';
$body['sender']='Test_sender';
$body['recipient']=config('app.test_recipient');
$body['message_body']='Test body';
$body=json_encode($body);
$URI_Response = $client->request('POST',$URI,['body'=>$body]);
$URI_Response =json_decode($URI_Response->getBody(), true);
return $URI_Response;
Note: I would suggest you to handle error please refer GuzzleDocumentation
That is proper error handling:
use GuzzleHttp\Client;
use GuzzleHttp\Exception\RequestException;
try {
$response = $client->get(YOUR_URL, [
'connect_timeout' => 10
]);
// Here the code for successful request
} catch (RequestException $e) {
// Catch all 4XX errors
// To catch exactly error 400 use
if ($e->getResponse()->getStatusCode() == '400') {
echo "Got response 400";
}
// You can check for whatever error status code you need
} catch (\Exception $e) {
// There was another exception.
}
Implementation: http://guzzle.readthedocs.org/en/latest/quickstart.html
You can handle errors like this
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use GuzzleHttp\Exception\RequestException;
use Exception;
try{
$client = new Client();
$response = $client->request('POST', $url,[
'headers' => $header,
'form_params' => $form-params
]);
$body = $response->getBody();
$status = 'true';
$message = 'Data found!';
$data = json_decode($body);
}catch(ClientException $ce){
$status = 'false';
$message = $ce->getMessage();
$data = [];
}catch(RequestException $re){
$status = 'false';
$message = $re->getMessage();
$data = [];
}catch(Exception $e){
$this->status = 'false';
$this->message = $e->getMessage();
$data = [];
}
return ['status'=>$status,'message'=>$message,'data'=>$data];
Here below i have attached my api request
$apiKey = "XXXX";
$Secret = "XXX";
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/hotels";
$request = new http\Client\Request("POST",
$endpoint,
[ "Api-Key" => $apiKey,
"X-Signature" => $signature,
"Accept" => "application/xml" ]);
try
{ $client = new http\Client;
$client->enqueue($request)->send();
$response = $client->getResponse();
if ($response->getResponseCode() != 200) {
printf("%s returned '%s' (%d)\n",
$response->getTransferInfo("effective_url"),
$response->getInfo(),
$response->getResponseCode()
);
} else {
printf($response->getBody());
}
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}'
getting following error
Uncaught Error: Class 'http\Client\Request' not found in
You need to add a use statement.
use http\Client\Request;
$request = new Request(blah blah);
Of course I assume you are using Composer autoloader. If not, you will also need to require_once() the file.
You can try using cURL instead of pecl_http. Here is an example:
<?php
// Your API Key and secret
$apiKey = "yourApiKey";
$Secret = "yourSecret";
// Signature is generated by SHA256 (Api-Key + Secret + Timestamp (in seconds))
$signature = hash("sha256", $apiKey.$Secret.time());
$endpoint = "https://api.test.hotelbeds.com/hotel-api/1.0/status";
echo "Your API Key is: " . $apiKey . "<br>";
echo "Your X-Signature is: " . $signature . "<br><br>";
// Example of call to the API
try
{
// Get cURL resource
$curl = curl_init();
// Set some options - we are passing in a useragent too here
curl_setopt_array($curl, array(
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $endpoint,
CURLOPT_HTTPHEADER => ['Accept:application/json' , 'Api-key:'.$apiKey.'', 'X-Signature:'.$signature.'']
));
// Send the request & save response to $resp
$resp = curl_exec($curl);
// Check HTTP status code
if (!curl_errno($curl)) {
switch ($http_code = curl_getinfo($curl, CURLINFO_HTTP_CODE)) {
case 200: # OK
echo "Server JSON Response:<br>" . $resp;
break;
default:
echo 'Unexpected HTTP code: ', $http_code, "\n";
echo $resp;
}
}
// Close request to clear up some resources
curl_close($curl);
} catch (Exception $ex) {
printf("Error while sending request, reason: %s\n",$ex->getMessage());
}
?>
Just make sure that first you uncomment ;extension=php_curl.dll in your php.ini file and restart your server.
We are planning to update our examples in the developer portal because some are outdated or not well documented.
Hi I am attempting to echo out data returned from an api I'm working with utilizing the following code:
<?php
ini_set("include_path", '/home/matthewt/php:' . ini_get("include_path") );
// This sample uses the Apache HTTP client from HTTP Components
(http://hc.apache.org/httpcomponents-client-ga/)
require_once 'HTTP/Request2.php';
$url = $request->getUrl();
$headers = array(
// Request headers
'Ocp-Apim-Subscription-Key' => 'my_id',
);
$request->setHeader($headers);
$parameters = array(
// Request parameters
);
$url->setQueryVariables($parameters);
$request->setMethod(HTTP_Request2::METHOD_GET);
// Request body
$request->setBody("{body}");
try
{
$response = $request->send();
echo $response->getBody();
}
catch (HttpException $ex)
{
echo $ex;
}
Everything up until this point works great and returns json data that basically looks like this: (I shortened the amount of fields to save space)
[{"GameID":49810,"Season":2017},{"GameID":49811,"Season":2017}]
What I need to know is how to loop through this data to print out the results for each game. I know I have to use something like this:
$arr = json_decode();
foreach($arr as $item) { //foreach element in $arr
$game_id = $item['GameID']; //etc
}
But I'm not sure what needs to be decoded...is it $response ?
Thanks
If $response->getBody() contains your json, then json_decode it, then this will be your array of objects which you can loop over.
So try this:
// snip
try
{
$response = $request->send();
$arr = json_decode($response->getBody());
foreach((array) $arr as $item) { //foreach element in $arr
echo $item->GameID; //etc
echo $item->Season; //etc
}
}
catch (HttpException $ex)
{
echo $ex;
}
I use the following method to dispatch a Slim app's route in my PHPUnit tests:
protected function dispatch($path, $method='GET', $data=array())
{
// Prepare a mock environment
$env = Environment::mock(array(
'REQUEST_URI' => $path,
'REQUEST_METHOD' => $method,
));
// Prepare request and response objects
$uri = Uri::createFromEnvironment($env);
$headers = Headers::createFromEnvironment($env);
$cookies = [];
$serverParams = $env->all();
$body = new RequestBody();
// create request, and set params
$req = new Request($method, $uri, $headers, $cookies, $serverParams, $body);
if (!empty($data))
$req = $req->withParsedBody($data);
$res = new Response();
$this->headers = $headers;
$this->request = $req;
$this->response = call_user_func_array($this->app, array($req, $res));
}
For example:
public function testGetProducts()
{
$this->dispatch('/products');
$this->assertEquals(200, $this->response->getStatusCode());
}
However, as much as things like the status code and header are in the response, (string) $response->getBody() is empty so I cannot check for the presence of elements in the HTML. When I run the same route in the browser, I get the expected HTML output. Also, if I echo $response->getBody(); exit; and then view the output in the browser, I see HTML body. Is there any reason, with my implementation, I'm not seeing this in the my tests? (in the CLI, so different environment I guess)
$response->getBody() will be empty as you've set up the parsed body. It's easier to put it into the RequestBody as a string in the same way as it would be set if it came in over the wire.
i.e something like this:
protected function dispatch($path, $method='GET', $data=array())
{
// Prepare a mock environment
$env = Environment::mock(array(
'REQUEST_URI' => $path,
'REQUEST_METHOD' => $method,
'CONTENT_TYPE' => 'application/json',
));
// Prepare request and response objects
$uri = Uri::createFromEnvironment($env);
$headers = Headers::createFromEnvironment($env);
$cookies = [];
$serverParams = $env->all();
$body = new RequestBody();
if (!empty($data)) {
$body->write(json_encode($data));
}
// create request, and set params
$req = new Request($method, $uri, $headers, $cookies, $serverParams, $body);
$res = new Response();
$this->headers = $headers;
$this->request = $req;
$this->response = call_user_func_array($this->app, array($req, $res));
}