Laravel 5: Send a response first, then process request in controller - php

I'm working with the Classic Paypal API and I'm stuck on a problem of responding before I process the request data.
public function store() {
// Send an empty HTTP 200 OK response to acknowledge receipt of the notification
response("", 200);
// Build the required acknowledgement message out of the notification just received
// Once it hits this point, nothing is sent to the client.
}
I know that in order for the client to receive the HTTP 200 response, I will need to add the return keyword in front of it. However, if I return the response immediately, then the processing of the request will not occur. I looked into before and after middlewares, but unfortunately they are not asynchronous. Is there any way of accomplishing a send then process in Laravel 5?

I found a hack solution to this problem:
try {
return response("", 200);
} finally {
// Controller logic here
}

I found this, looks cleaner
response('Response', 200)->send();
// Continue with the script
// Don't forget to exit the script

Related

Slim v3 how to send a response to a different URL / Ip address?

i try to implement the paypal IPN with slim.
see code here
they use curl to make a post request to an URL. Is it not possible to just change the URL in the slim response object?
other ways to send requests to somewhere with slim?
EDIT
I am talking about this line:
$res = curl_exec($ch);
what is the equivalent slim way to send a request to some url?
You can send PSR7 Requests with the help of HTTPlug.
You have to create some Adapter classes to tell HTTPlug how to create Slims Request and Response objects. In your code you just create your Slim Request and call the Client with this. You can choose between some clients, for example Curl or Socket.
If you want to send your user to PayPal in order for them to pay, then you need to create a form on your website which POSTs to PayPal directly.
The code you linked to is a POST request from PayPal back to your server. To handle that in Slim, you create a post route:
$app->post('/paypal-ipn', PayPalIpnAction::class);
Within your Action class you need to send POST request back to PayPal:
class PayPalIpnAction
{
public function __invoke($request, $response, $args)
{
$dataFromPaypal = $reqest->getParsedBody();
// Validate data from PayPal using HTTPlug, Guzzle or
// you use can the PayPal example code directly.
// If data is valid, process data and do whatever you
// need to with it.
// All done. Return the response.
return $response;
}
}
Note that the verification step back to PayPal isn't directly related to the handling of the notification in Slim as it's part of your code for handling the notification.

Guzzle asynch request not working

I'm using Guzzle that I installed via composer and failing to do something relatively straightforward.
I might be misunderstanding the documentation but essentially what I'm wanting to do is run a POST request to a server and continue executing code without waiting for a response. Here's what I have :
$client = new \GuzzleHttp\Client(/*baseUrl, and auth credentials here*/);
$client->post('runtime/process-instances', [
'future'=>true,
'json'=> $data // is an array
]);
die("I'm done with the call");
Now lets say the runtime/process-instances runs for about 5mn, I will not get the die message before those 5mn are up... When instead I want it right after the message is sent to the server.
Now I don't have access to the server so I can't have the server respond before running the execution. I just need to ignore the response.
Any help is appreciated.
Things I've tried:
$client->post(/*blabla*/)->then(function ($response) {});
It is not possible in Guzzle to send a request and immediately exit. Asynchronous requests require that you wait for them to complete. If you do not, the request will not get sent.
Also note that you are using post instead of postAsync, the former is a synchronous (blocking) request. To asynchronously send a post request, use the latter. In your code example, by changing post to postAsync the process will exit before the request is complete, but the target will not receive that request.
Have you tried setting a low timeout?

REST API - HTTP status codes with multiple errors

I'm currently in the process of creating a small API. I have some error conditions, the 3 in question in this case are:
The user making a request with any method other than POST
The user not being authenticated
An entity not being found; resulting in no action being able to be made.
In that order. I had originally decided that I could assign a status code to each of these errors, (i.e. 400, 403, and 404, in that order) but then realised that I can't set multiple HTTP status codes.
How does one deal with this issue? Should I use HTTP status codes?
In my view it should check each of these conditions in the order you specified and return immediately with the corresponding error code if one of the conditions fail.
So only 1 error code will be returned.
It would be OK to use HTTP status codes, but it depends on who is consuming your API. Sometimes it is better to just return 200 OK and then include Error information in the body.
With Status Codes
If you go with status codes just return the first error encountered, no use in handling the request further anyways, so in pseudo:
if (request is not POST) return 405; //abort here
//we know request is POST here
if (request not auhtorized) return 401; //abort here
//we know request is POST and authorized
if (request requests a not exisiting entity) return [404, 422, ..., 5xx] either will do; // abort here
// we now know the request is POST, autorized and requests valid information
processRequest();
Without Status Codes
As an alternative, since you tagged ajax, I assume you are returning JSON, so just return 200 OK and include a the fields success : [true|false] and errorMessage : ["Not POST"|"Bad Auth"|"Bad Request or Unknown resource"|"OK"] in your JSON answer.
You could also combine both ways, but depending on the ajax client not all will work well with all status codes. Given the information in the answer, all you need to do is check if success === true and handle error otherwise.

Return a HTTP 200 Code to the POST client?

I have a server sending POST to me. I need to reply with HTTP 200 OK.
Server needs kind of like a "Go Ahead!" prompt before it executes another action.
It requires a HTTP 200 response.
EDIT
I've tried the header(), but the server for some reason won't read it?
The 200 code is a standard response to a successful request... Even echoing out an empty json string would result in a 200 OK status.
echo json_encode(array());
If all you want to do is signal to your client that some process was completed, you can just echo back a custom status message or even a blank object like I demonstrated above.
If you want to actually manually send the 200 header you can do so like this -
header('Status: 200');
Make sure that this header is send before you have any output from the server.
This function call does the job:
http_response_code(200);
See: http://php.net/manual/en/function.http-response-code.php
This function call can be thrown anywhere in the server code -- the order of when this function is called does not seem to matter.

sending a response from a php script to iOS

I am creating an iPhone app which sends a username and password to a php script, the php script then looks in a mySQL database for the values and sets a boolean to either 0 or 1, depending on whether or not the user should be authenticated. I really have no idea where to start or even what I should Google to look into how to do this.
Is this feasible?
Is this the proper way to authenticate a user in an iOS app?
Thanks!
There are various types to achieve this.
a) Generate an XML or JSON file in PHP, and read the content back in iOS. (this method gives you the benefit of fetching any extra data if you want).
b) Send back HTTP header() from PHP, and read the HTTP response code. you can do something like this.
function checkLogin()
{
//Check login
if($login == true) {
header('HTTP/1.1 200 OK');
} else {
header('HTTP/1.1 401 Unauthorized');
}
}
c) You can output anything in PHP(plain text, JSON, HTML etc.), as the output generated by PHP will be received as HTTP response.
Anything the PHP script outputs will be returned as the HTTP response. Simply output something meaningful, and read it in the client.
The simplest solution would be to use HTTP status codes. Then you don't even have to care about the response body.
If authenticated: "HTTP 200 OK"
If unauthorized: "HTTP 401 Unauthorized"
Resource: http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
You can write a php script like this:
<?php
// the authentication procedures memorized in the $authentication variable the result of authentication process. Supposed to be 1 if successful
echo $authentication;
?>
Call this script from your iOS by using an NSURLRequest object for example.
P.S.: However, for data exchange between the client and the server you should use the JSON format.

Categories