I started learning PHP Slim-Framework v3. But I'm finding it difficult on few occasions.
Here is my code:
$app = new \Slim\App(["settings" => $config]);
$app->get('/', function(Request $request, Response $response, $args = []) {
$error = array('result' => false, 'message' => 'Bad Request', 'dev'=>'', 'data' => []);
$response->withStatus(500)->getBody()->write(json_encode($error));
});
Now I want to respond with status 500 to the user when ever I have issues in service. But unfortunately this is not working. Though I'm getting a response, it is returning 200 status instead of 500.
Am I doing something wrong or am I missing something?
I tried looking into other issues but I did not find anything helping me out.
The Response-object is immutable, therefore it cannot be changed. The methods with*() do return a copy of the Response-object with the changed value.
$app->get('/', function(Request $request, Response $response, $args = []) {
$error = array('result' => false, 'message' => 'Bad Request', 'dev'=>'', 'data' => []);
$response->write(json_encode($error)); // helper method for ->getBody()->write($val)
return $response->withStatus(500);
});
See this answer why you dont need to reassign the value on write.
You can also use withJson instead:
$app->get('/', function(Request $request, Response $response, $args = []) {
$error = array('result' => false, 'message' => 'Bad Request', 'dev'=>'', 'data' => []);
return $response->withJson($error, 500);
});
Related
I'm new in laravel and open api, if anyone can understand this question, I do some log to check if the code connect to the external api. How do I get the external api uri instead of the localhost? or does it means that I still cannot get through to the server?
link
Also this is the code that I try to make the log
public function handle(Request $request, Closure $next)
{
$response = $next($request);
if (app()->environment('local')) {
$log = [
'URI' => $request->getUri(),
'HEADER' => $request->header,
'METHOD' => $request->getMethod(),
'REQUEST_BODY' => $request->all(),
'RESPONSE' => $request->getContent(),
];
Log::info(json_encode($log));
}
return $response;
}
Using Guzzle, I'm consuming some external apis in JSON format,
usually I get the data with
$data = $request->getBody()->getContents();
But i can't get data from this different api.
It seems the data doesn't come in a 'Response Body'.
This api call works:
https://i.ibb.co/80Yk6dx/Screenshot-2.png
This doesn't work:
https://i.ibb.co/C239ghy/Screenshot-3.png
public function getRemoteCienciaVitaeDistinctions()
{
$client = new Client(['headers' => ['Accept' => 'application/json']]);
$request = $client->get(
'https://................/',
[
'auth' => ['...', '...'],
]
);
$data = $request->getBody()->getContents();
return $data;
}
the second call is working fine, but the response is empty,
as we can see in Screenshot-3, the Total = 0, so the response from this API is empty.
to handle that properly I suggest you this modification for your method :
public function getRemoteCienciaVitaeDistinctions()
{
$client = new Client(['headers' => ['Accept' => 'application/json']]);
$request = $client->get(
'https://................/',
[
'auth' => ['...', '...'],
]
);
//Notice that i have decoded the response from json objects to php array here.
$response = json_decode($request->getBody()->getContents());
if(isset($response->total) && $response->total == 0) return [];
return $response;
}
please check the documentation of the API that you are using
I'm building a small application in Laravel 5.5 where I'm using Guzzle Http to get call the api url and get the response, Few of the api calls have certain condition to have headers which works as authorization of the request generated. I'm trying to place the header something like this:
public function post(Request $request)
{
try {
if ($request->url_method == 'get') {
$request = $this->client->get($request->url, [ 'headers' => [ 'access_token' => $request->headers->access_token]]);
}
else if ($request->url_method == 'post')
{ $request = $this->client->post($request->url, [$request->request_data]); }
else { return response()->json(['data' => 'Invalid Method'],500); }
$response = \GuzzleHttp\json_decode($request->getBody());
return response()->json(['data' => json_decode($response->d)], $request->getStatusCode());
}
catch (ClientException $e) {
return response()->json(['data' => 'Invalid Request.'], $request->getStatusCode());
}
}
But this is giving me errors:
Undefined property: Symfony\Component\HttpFoundation\HeaderBag::$access_token
Please checkout the screenshot:
Also when calling through the browser in console it gives me the same error:
Help me out in this, Thanks.
try this code
use GuzzleHttp\Client as GuzzleClient;
..
..
..
$headers = [
'Content-Type' => 'application/json',
'AccessToken' => 'key',
'Authorization' => 'Bearer token',
];
$client = new GuzzleClient([
'headers' => $headers
]);
$body = '{
"key1" : '.$value1.',
"key2" : '.$value2.',
}';
$r = $client->request('POST', 'http://example.com/api/postCall', [
'body' => $body
]);
$response = $r->getBody()->getContents();
Try to add bearer in all small cases before access token like following -
$access_token = 'bearer '.$request->headers->access_token
I am using Guzzle (v6.1.1) in PHP to make a POST request to a server. It works fine. I am adding some logging functions to log what was sent and received and I can't figure out how to get the data that Guzzle sent to the server. I can get the response just fine, but how do I get the sent data? (Which would be the JSON string.)
Here is the relevant portion of my code:
$client = new GuzzleHttp\Client(['base_uri' => $serviceUrlPayments ]);
try {
$response = $client->request('POST', 'Charge', [
'auth' => [$securenetId, $secureKey],
'json' => [ "amount" => $amount,
"paymentVaultToken" => array(
"customerId" => $customerId,
"paymentMethodId" => $token,
"publicKey" => $publicKey
),
"extendedInformation" => array(
"typeOfGoods" => $typeOfGoods,
"userDefinedFields" => $udfs,
"notes" => $Notes
),
'developerApplication'=> $developerApplication
]
]);
} catch (ServerErrorResponseException $e) {
echo (string) $e->getResponse()->getBody();
}
echo $response->getBody(); // THIS CORRECTLY SHOWS THE SERVER RESPONSE
echo $client->getBody(); // This doesn't work
echo $client->request->getBody(); // nor does this
Any help would be appreciated. I did try to look in Guzzle sourcecode for a function similar to getBody() that would work with the request, but I'm not a PHP expert so I didn't come up with anything helpful. I also searched Google a lot but found only people talking about getting the response back from the server, which I have no trouble with.
You can do this work by creating a Middleware.
use GuzzleHttp\Client;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Middleware;
use Psr\Http\Message\RequestInterface;
$stack = HandlerStack::create();
// my middleware
$stack->push(Middleware::mapRequest(function (RequestInterface $request) {
$contentsRequest = (string) $request->getBody();
//var_dump($contentsRequest);
return $request;
}));
$client = new Client([
'base_uri' => 'http://www.example.com/api/',
'handler' => $stack
]);
$response = $client->request('POST', 'itemupdate', [
'auth' => [$username, $password],
'json' => [
"key" => "value",
"key2" => "value",
]
]);
This, however, is triggered before to receive the response. You may want to do something like this:
$stack->push(function (callable $handler) {
return function (RequestInterface $request, array $options) use ($handler) {
return $handler($request, $options)->then(
function ($response) use ($request) {
// work here
$contentsRequest = (string) $request->getBody();
//var_dump($contentsRequest);
return $response;
}
);
};
});
Using Guzzle 6.2.
I've been struggling with this for the last couple days too, while trying to build a method for auditing HTTP interactions with different APIs. The solution in my case was to simply rewind the request body.
The the request's body is actually implemented as a stream. So when the request is sent, Guzzle reads from the stream. Reading the complete stream moves the stream's internal pointer to the end. So when you call getContents() after the request has been made, the internal pointer is already at the end of the stream and returns nothing.
The solution? Rewind the pointer to the beginning and read the stream again.
<?php
// ...
$body = $request->getBody();
echo $body->getContents(); // -->nothing
// Rewind the stream
$body->rewind();
echo $body->getContents(); // -->The request body :)
My solution for Laravel from 5.7:
MessageFormatter works with variable substitutions, see this: https://github.com/guzzle/guzzle/blob/master/src/MessageFormatter.php
$stack = HandlerStack::create();
$stack->push(
Middleware::log(
Log::channel('single'),
new MessageFormatter('Req Body: {request}')
)
);
$client = new Client();
$response = $client->request(
'POST',
'https://url.com/go',
[
'headers' => [
"Content-Type" => "application/json",
'Authorization' => 'Bearer 123'
],
'json' => $menu,
'handler' => $stack
]
);
You can reproduce the data string created by the request by doing
$data = array(
"key" => "value",
"key2" => "value",
);
$response = $client->request('POST', 'itemupdate', [
'auth' => [$username, $password],
'json' => $data,
]);
// ...
echo json_encode($data);
This will output your data as JSON string.
Documentation at http://php.net/manual/fr/function.json-encode.php
EDIT
Guzzle has a Request and a Response class (and many other).
Request has effectively a getQuery() method that returns an object containing your data as private, same as all other members.
Also you cannot access it.
This is why I think manually encode it is the easier solution.
If you want know what is done by Guzzle, it also have a Collection class that transform data and send it in request.
I am using the HttpFoundation in my small project: use \Symfony\Component\HttpFoundation\JsonResponse as JsonResponse;
Unfortunately all my responses (tried JsonResponse, Response and BinaryFileResponse) only return a blank page, no errors and the code gets executed normally, e.g.
/* Get Inputs */
if (!$data = filter_input(INPUT_GET, 'url', FILTER_VALIDATE_URL)) {
return new JsonResponse(array(
'result' => 'error',
'message' => 'URL is invalid or missing'
));
}else{
return new JsonResponse(array(
'result' => 'success',
'message' => 'FINE'
));
There are no errors in the logs either.
Any ideas how to approach the issue?
//UPDATE FOR CLARIFICATION
$json = new JsonResponse(array(
'result' => 'error',
'message' => 'Encrypt is invalid or missing'
));
echo $json;
returns HTTP/1.0 200 OK Cache-Control: no-cache Content-Type: application/json {"result":"error","message":"Encrypt is invalid or missing"}
but why does the return not work?
You're not using the full stack framework, so you need to be sure that your front controller or equivalent calls $response->send(); to deliver the response to the client.
It's addition to answer:
$response = new JsonResponse(array(
'result' => 'error',
'message' => 'Encrypt is invalid or missing'
));
$response->send();