HttpSendRequest not waiting for PHP script to finish - php

I'm sending an HTTP POST request from my C++ app to a PHP script on a server. Using HttpOpenRequest/HttpSendRequest/etc. Currently it waits for the PHP script to finish executing before HttpSendRequest returns. Is there anyway to change this functionality?
I'm sending the data just before my C++ application closes, so I don't want it to sit there for 10+ seconds waiting for the PHP script to finish executing. I just want it to send the data, then close the app.
One thing I was thinking was to have the PHP script spawn another PHP script in a different process using the exec command, so the first script would return straight away. However, I'm sending a lot of data with my HTTP POST request, so would need it pass this data to the spawned process.
Ideally I just want a flag to set to tell HttpSendRequest not to wait. I couldn't see anything obvious in the docs, but may have missed something.

You can call InternetOpen with the INTERNET_FLAG_ASYNC and have your callback do nothing of consequence.
Here's some example code to get you started:
http://www.codeproject.com/KB/IP/asyncwininet.aspx
Then (as rik suggests), call ignore_user_abort(true); at the top of your PHP script to ensure it executes fully.
ignore_user_abort

You may want to ignore_user_abort() in your PHP script. Then you can close the connection from your C client after the data is sent and PHP will continue to do whatever it's supposed to do.

Related

How can I execute a PHP script without waiting for completion before the page loads for the end user?

I am working on a site plugin that takes advantage of the YouTube API to grab some data for a specific channel. The problem is that the code takes several seconds to load on larger channels meaning the user has to wait quite a bit of time for the script to finish loading before they can view each page. Most of the time the data retrieved isn't even relevant to them but the script still needs to run its checks. So how can I initialize the PHP script without the user having to wait for it?
My first thought is to use AJAX and make a request to the remote script but will that cause parts of the page to hang as the script is running? I don't need the results from the script, I just need the script to run and do its own thing.
You can use exec to start a separate PHP script. And adding & at the end will make exec return imidiately.
Let script.php do the heavy stuff and call it from a mall script like so:
exec("php script.php > /dev/null &");
You need to have a *nix server environment. Don't think it will work on Windows platform.
AJAX stands for Asynchronous JavaScript and XML, which means that, when using it, the execution of the rest of the code will not be blocked.
You can make an AJAX request to the script you want to execute and then keep rendering the page normally. The AJAX request will be performed in the background, and won't be of any disturb whatsoever.

Terminate PHP script on server through AJAX call

I have written a PHP script to import large amount of data. The import process is triggered through Ajax call and the ajax request keep on waiting for the server response. As I am working on a dedicated server so there is no issue of timeout.
The problem is that we require a feature by which we can terminate the import process. For example a stop button on client-side. We thought that if we had killed the waiting ajax call then the process on the server will also stop as there is no request to serve. But unfortunately that is not the case, the script keeps on executing on server side while the Ajax Request is already killed from client.
Secondly, we use PHP session in this project. Let say if the cancel button requires an Ajax call to another script on the server to stop the process then How could that request will reach server if there is already a waiting ajax request. Php/Apache will hold the second request until the first request cycle is completed.
Note: As per our project architecture we require session_start() on every page. It will be good if anyone can guide on these issues.
You can write the Process ID at the start of running the script to a file, the db or a cache. You can get the Process ID with http://php.net/manual/en/function.getmypid.php. This assumes each script has its own Process ID.
The kill script (not using the locked session) could read that Process ID and try to kill it.
Be careful while doing long running processes in PHP as PHP's zend engine & GC is not suited for long running processes.
So, I strongly suggest using a proper job manager like gearman. gearman does have a php extensions. Using a job manager will give you full control over each process. you can start/stop processes & taks.
Another option is to use a queue, like amqp, to handle these tasks more cleanly. Which one is more suitable for your use case, I'll let you decide.
How about setting a time limit slightly higher than your AJAX timeout on your PHP script? This should kill the PHP script if it runs over time. Something similar to this:
<?php
set_time_limit(20);
while ($i<=10)
{
echo "i=$i ";
sleep(100);
$i++;
}
?>
Source: http://php.net/manual/en/function.set-time-limit.php
Once a script runs it can only be stopped by ending the php process working on the script. One possibility would be to use the session to store a "continue" condition when another script is called.
For example:
Script 1 is the worker (importer)
Script 2 is a function called repeatedly by ajax as long as the importer shall work.
Script 1 and 2 share let's say $_SESSION['lastPing'].
so
Script 2 sets $_SESSION['lastPing'] = time(); on each call.
Script 1 has a condition if($_SESSION['lastPing'] - 30 > time()){ die(); }
You might be able to handle this using the proc_ functions. A possible outline of the steps:
Create a unique token and pass it to the server along with the order to begin the import.
When order to import is received (via AJAX):
a) Store a record showing that this token is being processed (via file, db, memcached).
b) Run the import script using proc_open.
c) Begin a polling loop, checking the record from (2a) to see that this token is still in processing status. If not, call proc_terminate and exit the loop.
If the order to stop import is given (in a separate AJAX call), update the persisted record to indicate that the particular token should be stopped, which will be picked up in (2c)
Goto the following link for the exact solution to your problem:
PHP auto-kill a script if the HTTP request is cancelled/closed

Starting a task to continue after a PHP script finishes

I have a PHP script which is run by AJAX. At the end of the script, the server makes an HTTP request to a different server to log the successful completion of the script. The problem is, this second server sometimes takes a while to respond, and I would like this to happen after the AJAX client finishes its request.
Is there some PHP library or similar which could do this? Is my best bet to log the completion to a file on the first server, then have a cron script making the HTTP requests to the second server based on the contents of the file?
U can use file_get_contents to call a remote server from your PHP, or use the more complex, but more feature rich CURL wrapper library PHP has.

PHP: how does http_get work?

Let's say I have an index.php where I use some form of http get/post operation. How exactly is this executed by the server? does it pause and wait for a response before completing execution? What if nothing is returned? What if I want the execution to continue and another script to be executed once the response arrives (as in Ajax)?
enlightenment appreciated.
It's a simple matter of logic.
Does it pause and wait for a response before completing execution?
Yes.
What if nothing is returned?
Then you either get false or a empty string.
What if I want the execution to continue and another script to be executed once the response arrives (as in Ajax)?
You need to play with libevent (not for the soft-hearted - a lot harder than Ajax).
Server receives the request (let's say it's Apache), it recognizes someone is requesting a .php file so it knows it has to pass the request to PHP engine. PHP engine receives the request and parses the headers into $_POST / $_GET / $_FILES ($_REQUEST) superglobals so that it can be worked with.
During this time the execution is as follows:
Client requests a resource from the server.
Server receives it and does certain work to return response (in this case it invokes PHP engine).
PHP engine does what it has to do and returns a result (be it a valid result or a parse error - server doesn't care). In any way, if nothing went wrong server will return a response with appropriate response status code (2xx, 3xx, 4xx, 5xx, you probably know of 404 already).
Once Apache receives response from PHP, script execution is stopped.
It's not full-duplex communication where you can have socket open at all times to be used as a telephone wire (think Skype or any other IM).
In case of Javascript and async calls - since JS is asynchronous language (it implements an event loop rather than threaded model), you specify a callback function to be executed when the response arrives. Depending on what you need, you can send yet another request to the server.
However, there's the WebSocket protocol that enables full-duplex communication which leaves the connection open and where server can push the data to the client. It requires a different server than Apache / Nginx such as Node.js or a custom one.
Reading from the docs, it seems like http_get is a blocking call, i.e. it will freeze your script until the HTTP transaction completes, fails or timeouts. It seems like you cannot set it in non-blocking mode, and PHP has no threads. I'm not an expert in PHP, but I think there's no easy way to continue the script.
Besides the question itself, if I were you, I would really reconsider my choices. I feel like you're not thinking it the right way, because I can hardly imagine a scenario where it's strictly needed to perform an HTTP GET in PHP. It is done very, very rarely.
PHP scripts do not continue running in any fashion unless the page is still being passed to the browser. If your browser's "Loading" icon isn't spinning, then PHP has stopped being executed. They run and then terminate almost instantaneously (for reasonably-sized pages).
When you pass an HTTP GET/POST signal, you're passing it to a PHP script, but not one that is already running and waiting for a response. It's an entirely new instantiation of the script, which has to re-assign everything, re-include everything, and re-grab everything from the database, if you're using one.
The index.php will be executed and terminated right away.
If there's a request post to the php, the php file will be executed (again, if it's index.php) and terminated.
You can use exec() function to execute your script in your php file.

PHP, Ajax, and the lifespan of the request

I was wondering about the lifespan of a PHP script when called via Ajax. Assume that there is a long-running (i.e. 30 seconds) PHP script on a server and that page is loaded via Ajax. Before the script completes, the user closes the browser. Does the script continue running to completion, is it terminated, or is this a function of the server itself (I'm running Apache fwiw). Thanks for any help.
This may be of interest: ignore_user_abort()
ignore_user_abort — Set whether a client disconnect should abort script execution
However note
PHP will not detect that the user has aborted the connection until an attempt is made to send information to the client.
The script will continue running. Closing the browser on the client does not notify the server to stop processing the request.
If you have a large time consuming script, then I would suggest splitting it up into chunks. Much better that way

Categories