Uploading an XML file using cURL - php

I am uploading an xml file to a supplier url. Not the content as a post, but the file itself. Regarding the response from the server, the instructions read as follows.
"For each OrderRequest from a client, the server will reply with a single OrderRequestResponse."
And:
"Once a successful order request is received, it will be placed in the queue to be run. The client shall not wait for this report to be generated – the communication over the HTTP socket will only consist of two messages – an OrderRequest, and an OrderRequestResponse."
It then goes on to say that the response may happen anywhere between 1 and 5 minutes later.
So the question is this - I would like to see the respose and make sure that the order has been accepted correctly, but how do i code for this given that i can't leave my cURL routine open for 5 minutes waiting. Can i tell the cURL request where to send the response within the parameters and then close the curl session and have my location process the response to email me or act on the content of the response.
Here is my upload code so far:
$xml = curl_file_create($thefile);
$data = array('test_file' => $xml);
$url = "www.supplierlocation.co.uk/etc";
$curlSession = curl_init();
curl_setopt ($curlSession, CURLOPT_URL, $url);
curl_setopt ($curlSession, CURLOPT_POST, 1);
curl_setopt ($curlSession, CURLOPT_POSTFIELDS, $data);
$ch_result = curl_exec($curlSession);
curl_close($curlSession);
What, if anything can i add so that the respose ends up somewhere that i can deal with it even after the session is closed.
[Does anybody know where i can find example of php code to respond to the response post my side. It would be an XML file that is received.]
Thanks,

Related

PHP cURL request takes up the entire Timeout

I currently have a Laravel application, which is doing a CURL request from one route to another route within the same route. My CURL looks like this:
//LOGGING THAT A CURL CALL IS ABOUT TO BE MADE
$url = env('APP_URL') . '/tests/add/results';
$ch = curl_init();
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //return server error
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLINFO_HEADER_OUT, FALSE);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS, $test_post_data);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
$response = curl_exec($ch);
In the route, that the POST is being sent to, the first thing i log, is the request data:
//LOGING THAT I RECEIVED THE CURL CALL in receiving function
I'm noticing, that the logs for the request data get logged exactly the same amount of time as the timeout, meaning the request is actually being sent 10 seconds after the initial call.
In my logs i'll see something like:
10:10:10 - LOGGING CURL CALL
10:10:20 - Recieving CURL call
If i change the timeout to 30, then the log shows 30 seconds later that i received the CURL call.
Does anyone have any idea why this may be happening?
The response from the CURL just comes back as false always.
I did the following to make a post request work:
Instead of calling the route via CURL i did a post directly to the route function
$testController = new TestsController;
$test_data_request = new \Illuminate\Http\Request();
$test_data_request->setMethod('POST');
$test_data_request->request->add( $test_post_data );
$testId = $testController->addTestResults($test_data_request);
You've not provided enough information, but i think, the problem will be one or more of the following:
The WebServer http://127.0.0.1:8000 is not running
The script located on http://127.0.0.1:8000/tests/add/results is running too long and the request timeouts before it is completed
The requested path is returning redirect headers and creates an infinite loop
The response is too big to finish the data transfer in thirty seconds (very wierd if on localhost)
Try some more debugging and provide more information on this, so we may help you.
PS: Firstly i would try to catch the headers (curl_setopt($ch, CURLINFO_HEADER_OUT, true);) and print out the response (var_dump($response);) - or save it to some file :)

Display Curl Response Sequential one by one

I have simple POST CURL request script,
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_POST, 1);
$result = curl_exec($ch);
The problem i am facing is, if i fetch post data from db or i fetch post data from a form, when i process data in large quantity, for example 60 times. The curl displays the output until and unless all 60 requests are completed.
I want the curl to display output one by one not all at once when the query is completed e.g.
Echo 1st Response
Echo 2nd Response
Echo 3rd Response
What you are requesting appears to be undefined.
PHP, and any other HTTP Server can only start sending data, when the data-length is know. When echoing, your server is supposed to assemble the reply, then organize a transfer.
If you want to assemble a document, that can be done, use AJAX, or any other request/reply system to assemble divs/fields each.
An example would be:
"Base document" -> [N] divs or fields. Each field requests its related procesing.
When basereceives data, it assembles in its related div.

Local API Calls Interspire

I have Interspire(email marketing) installed on my server. API calls can be sent to a php file that handles xml requests. I am using curl to send the request and it looks like this
$ch = curl_init($this->api_endpoint);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
$result = #curl_exec($ch);
return $result;
$this->api_endpoint is a url that points to the php file that handles the xml request.
I am trying to make the whole thing work faster and I thought if I didn't have to sent the request out to the internet and back maybe I could save some time, but I am not sure if it is possible to send the request "locally"... I'd like to possibly have $this->api_endpoint equivalent to ../../xml.php I have actually tried this, but it doesn't work. Can an API call be handled within a server and not need to be sent out to the internet to work?

PHP : understand the CURL timeout

From a php page, i have to do a get to another php file.
I don't care to wait for the response of the get or know whether it is successful or not.
The file called could end the script also in 5-6 seconds, so i don't know how to handle the get timeout considering what has been said before.
The code is this
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'http://mywebsite/myfile.php');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, false);
curl_setopt($ch, CURLOPT_TIMEOUT, 1);
$content = trim(curl_exec($ch));
curl_close($ch);
For the first task (Where you don't need to wait for response )you can start new background process and below that write code which will redirect you on another page.
Yeah, you definitely shouldn't be creating a file on the server in response to a GET request. Even as a side-effect, it's less than ideal; as the main purpose of the request, it just doesn't make sense.
If you were doing this as a POST, you'd still have the same issue to work with, however. In that case, if the action can't be guaranteed to happen quickly enough to be acceptable in the context of HTTP, you'll need to hive it off somewhere else. E.g. make your HTTP request send a message to some other system which then works in parallel whilst the HTTP response is free to be sent back immediately.

Does curl_exec() retry if timeout?

In my application I have to make a POST call to a webservice. They send me an XML response, basically saying "Accepted" or "Refused".
Last week I had an issue with one of these calls: I received a "Refused" response while their backend was telling me this request had been accepted.
I asked them what happened and they told me they received 2 requests (with the same ID - a parameter I send to them). First one was "Refused", second one was "Accepted".
I investigated: in my code, if I receive a "Refused" response, I log it, I update my database, and that's it. I do not try again.
The only thing would be PHP curl functions.
The day the problem occured, the webservice took unusual long time to response (20 seconds).
Could curl have made several calls? There is no retry option in the PHP function (or I didn't find it), but I'd rather ask here to be sure.
Here is my curl code.
$ch = curl_init();
$myArrayWithDatas = array( '...' );
$httpQueryFields = http_build_query($myArrayWithDatas);
$url = "https://www.webservice.com/api";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $httpQueryFields);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
if (empty($response)) {
// I log an error
// (no trace of that in my logs)
} else {
// I log the XML response
// (one "Refused" response logged)
}
curl_close($ch);
Is there any case where this code could send 2 or more requests to the $url?
curl_exec will only do 1 call.
Are you running your code via a cron job or scheduled task ? If that's the case, maybe your code has been launched twice and that would explain why there were two calls done.

Categories