Stop php script execution - php

I have php_mod and an apache server.
If I start a script from the browser it will persist until the execution is complete ( even if i close the browser )
How can i stop the process ?

Normally, if you're sending output, this doesn't happen: if the webserver detects a disconnect, the PHP process is also stoppend (which is why we have functions like register_shutdown_function to make sure something is done (unelss you encounter a fatal error of course)).
However, as HTTP is stateless, the only point in time the webserver will detect a disconnect is when it is trying to send content (see also the remarks at ignore_user_abort (default is false, which is what you want)). Depending on the context of the request, a workable kludge could be in big loops to send non-displayed data to the user, in HTML that could be to send whitespace and flush. This can end up in any buffer though, (PHP's, servers, other places in the network) so detection is still not 100%, but that is about unavoidable. A sane time limit to avoid infinite looping, and only upping that limit for requests that actually need them is about the best you can do.

Check whether ignore_user_abort(true) is being set anywhere in the script. Or if there is a php_value ignore_user_abort directive set in .htaccess

use in your script (if an amount of time has passed)
die();

Closing the browser does not kill the running process. If you want to stop the background process, you will have to kill the process.
If you are using windows, you can restart apache using Apache service manager or kill it using Task Manager.

Related

Running long process on Php/Apache/Ubuntu

I'm trying to run long process on Php/Apache/Ubuntu (AWS)
This is a simple process that builds a cache during the night.
The process can run for a few hours, and is initiate by crontab accessing a special url with curl.
Sometimes the process stops at a random with no error, I suspect that it is killed by the apache, although I set
#set_time_limit(0);
#ini_set('max_execution_time', -1);
Is it a known issue with Php/Apache/Ubuntu?
Is there a way to solve it?
Currently, my solution is to run the process every 5 minutes, and store the state on the disk, and continue from where it stopped.
But I would like to know more about this issue and if there is a better way to tackle it?
NOTE:
The process stops randomly or doesn't stop at all - the longer the process (i.e. bigger cache) the chance it will stop is higher
One possible reason is that the client disconnects (e.g. after a timeout): PHP stops the request processing by default in this case. To prevent this, you can use ignore_user_abort:
ignore_user_abort(true);
Also note that the set_time_limit call may actually fail (e.g. on a restricted environment) — so it might make sense to remove the error suppression (#) or explicitly check whether set_time_limit(0) returned true.

PHP manage web service with long execution without extending set_time_limit

I need to write a script that reads a big .csv and generates a file for each row.
Since on this server I can't modify timeout with set_time_limit, in my script that is manually executed in browser via http I get 10 row, execute my code for each, reach the end and auto reload for next 10 row, so on till I reach the end.
Now I need to convert this script into a web service, but I don't know how to avoid that the scripts timeout.
set_time_limit(900) // does not work
From reading here it seems it has a restriction.
This function has no effect when PHP is running in safe mode. There is no workaround other than turning off safe mode or changing the time limit in the php.ini.
Do you have safe mode enabled? If so, it seems you may have to disable it. You can also see other values that do the same/similar actions here, though they also require safe mode to be disabled.

PHP script stops running after some time run by browser

I have made a PHP script which probably would take about 3 hours to complete. I run it from browser and after about 45minutes it stops doing anything. I know this since its polling certain web addresses and then saves some data to database. So it basically stops putting any data to database which lead me to conclusion that it has stopped. It still shows in browser like it would be loading the page though but its neverending.
There arent any errors so it probably is some kind of timeout... But where it occurs is mystery or how can I prevent it from happening. In my case I cant use the CLI, I must user browser client to initiate the script.
I have tried to put
set_time_limit(0);
But it had no apparent effect. Any suggestions what could cause the timeout and a fix for it?
Try this:
set_time_limit(0);
ignore_user_abort(true);
ini_set('max_execution_time', 0);
Most webhosts kill processes that run for a certain length of time. This is intended as a failsafe against infinite loops.
Ask your host about this and see if there's any way it can be disabled for this particular script of yours. In some cases, the killer doesn't apply to Cron tasks, or processes run by SSH. However, this varies from host to host.
Might be the browser that's timing out, not sure if browsers do that or not, but then I've also never had a page require so much time.
Suggestion: I'm assuming you are running a loop. Load a page then run each iteration of the loop in an ajax call to another page, not firing the next iteration until the previous one returns.
There's a setting in PHP to kill processes after sometime. This is especially important for shared servers (you do not want that one process slows up the whole server).
You need to ask your host if you can make modifications to php.ini (through .htaccess). In particular the max_execution_time setting.
If you are using session, then you would need to look at 'session.cookie_lifetime' and not set_time_limit. If you are using an array, the array size might also fill up.
Without more info on how your script handles the task, it would be difficult to identify.

What happens when the server is in an infinite loop and the client stops?

I am trying to figure out how the "talking" between the server and the client is done.
So, when the server is generating an infinite loop, echoing"hello<br />", for example, what happens when the client stops, or hits 'back'?
How does the server know it's the end of the loop or does it take an endless process by its side?
Is there anywhere I can read about it just to get the big picture?
The client (browser) has a TCP/IP session established with your server, waiting for the HTTP response of your website. When the user hits back/cancel/close, this TCP connection is closed immediately by the client.
The webserver (i.e. apache) will inform the PHP interpreter of the TCP connection close.
Unless the php.ini directive ignore_user_abort is set to 1 (on server side, 0 is PHP default), the PHP interpreter will then abort script execution when the current atomic operation finishes (in your example: echo())
However, even when you set ignore_user_abort explicitly to 1 you will hit PHPs max_execution_time or the apache TimeOut (both are configurable on server side, too)
also see ignore_user_abort() and set_time_limit()
Even if your php script has an infinite loop, php.ini has a max_execution_time which will kill the process if the time exceeds.
I am not sure how it will work when the client closes a connection. Apache might kill the process but I don't think PHP will be notified of the client's connection closing.
If you do set_time_limit(0); in the script (so the PHP interpreter lets it run forever), then the script will probably run until the web server kills it after however long the TimeOut variable is set to (defaults to 300 seconds I think, and as far as I know is only an Apache setting).
See Apache's docs for the TimeOut directive.

Does php execution stop after a user leaves the page?

I want to run a relatively time consuming script based on some form input, but I'd rather not resort to cron, so I'm wondering if a php page requested through ajax will continue to execute until completion or if it will halt if the user leaves the page.
It doesn't actually output to the browser until a json_encode at the end of the file, so would everything before that still execute?
It depends.
From http://us3.php.net/manual/en/features.connection-handling.php:
When a PHP script is running normally
the NORMAL state, is active. If the
remote client disconnects the ABORTED
state flag is turned on. A remote
client disconnect is usually caused by
the user hitting his STOP button.
You can decide whether or not you want
a client disconnect to cause your
script to be aborted. Sometimes it is
handy to always have your scripts run
to completion even if there is no
remote browser receiving the output.
The default behaviour is however for
your script to be aborted when the
remote client disconnects. This
behaviour can be set via the
ignore_user_abort php.ini directive as
well as through the corresponding
php_value ignore_user_abort Apache
httpd.conf directive or with the
ignore_user_abort() function.
That would seem to say the answer to your question is "Yes, the script will terminate if the user leaves the page".
However realize that depending on the backend SAPI being used (eg, mod_php), php cannot detect that the client has aborted the connection until an attempt is made to send information to the client. If your long running script does not issue a flush() the script may keep on running even though the user has closed the connection.
Complicating things is even if you do issue periodic calls to flush(), having output buffering on will cause those calls to trap and won't send them down to the client until the script completes anyway!
Further complicating things is if you have installed Apache handlers that buffer the response (for example mod_gzip) then once again php will not detect that the connection is closed and the script will keep on trucking.
Phew.
It depends on your settings - usually it will stop but you can use ignore_user_abort() to make it carry on.
Depending on the configuration of the web server and/or PHP, the PHP process may, or may not, kill the thread when the user terminates the HTTP connection. If an AJAX request is pending when the user walks away from the page, it is dependent on the browser killing the request (not guaranteed) ontop of your server config (not guaranteed). Not the answer you want to hear!
I would recommend creating a work queue in a flat file or database that a constantly-running PHP daemon can poll for jobs. It doesn't suffer from cron delay but keeps CPU/memory usage to a usable level. Once the job is complete, place the results in the flat file/database for AJAX fetch. Or promise to e-mail the user once the job is finished (my preferred method).
Hope that helps
If the client/user/downloader/viewer aborts or disconnects, the script will keep running until something tries do flush new data do the client. Unless you have used
ignore_user_abort(), the script will die there.
In the same order, PHP is unable to determine if client is still there without trying to flush any data to the httpd.
found the actual solution for my case of it not terminating the connection. The SESSION on my Apache/Php server needed to close before the next one could start.
Browser waits for ajax call to complete after abort.

Categories