Hell all,
I have made use of the following ignore_user_abort.
ignore_user_abort(true); set_time_limit(0); session_start();
However, when I navigate away from the page which I fireoff an AJAX request, the script stops?
What am I doing wrong?
Update
In the PHP manual it says:
PHP will not detect that the user has
aborted the connection until an
attempt is made to send information to
the client. Simply using an echo
statement does not guarantee that
information is sent, see flush().
It seems to suggest you can use echo and it will just identify that the user has disconnected and it will continue?
PHP will not detect... until an attemt is made to send information to the client
This sounds to me like: when php can't flush its buffer to the client: stop. So I suggest using ob_start() to buffer everyting at the start of the page, you can also implement gzip this way: ob_start('ob_gzhandler').
Maybe your server has a built-in timeout that kills the script?
You should also note that you shouldn't use echo in an aborted script, because you have nowhere to send the output.
Some things to consider
Are you sure the user abort is causing the problem?
Have you checked the log to see if there are any errors logged.?
Does your server kill the script regardless of the the script itself?
Is the ajax call even being made? I assume it runs when the user navigates away.
You can use wireshark to watch the traffic between your browser and the webserver to make sure what you think is happening is actually happening.
DC
Related
I recently executed a mysql query via chrome and closed it out. How exactly does a browser stop a PHP script using the stop button? I thought PHP was a server-side language and could not be controlled through a client.
*UPDATE*I'm now aware of SHOW PROCESSLIST, but this only shows you which threads are running.Is there a SQL command I can use to view a executed query with great detail?
A client (Chrome) has nothing to do with the execution of scripts (PHP) on the server, which in turn have no control over database processes (MySQL query).
Look at your servers process list to see what's going on in general (Apache processes).
Or even better: use SHOW PROCESSLIST; on the MySQL console to find the long running query. You may quit it by using KILL ###ID_OF_QUERY###;.
No, you don't need to keep it open. If you exit a running car, does the car turn off? No.
Sorry, that came off a little snotty, but it wasn't intended too.
The browser, in your case Chrome, is not actually running the actual code. The server is. Thus, once the instruction is executed, closing the browser no longer matters as the request has been given to the server.
two functions are essential for executing time consuming php scripts.
it has nothing to do with the browser (as other users already pointed out)
lookup ignore_user_abort and set_time_limit
The script will continue to execute regardless of browser closure. You can free up your browser by sending the response and allowing the php process to continue on.
ignore_user_abort(true);
$response = "Processing!";
header("Connection: close");
header("Content-Length: " . mb_strlen($response));
echo $response;
flush();
// Insert your lengthy query here
The Answer is it depends, as others mentioned you can check what is running on the mysql server by using the show processlist;
If it is a single query that takes a long time, the it will most likely carry on running after the browser has closed. PHP will have sent the request to the Database and will in effect be sat waiting for it to complete, in turn the browser will be waiting for the webserver to finish building the page/resource that is on that url
so the request is: browser <-> web server (<-> php ) <-> mysql in an ideal world if the user cancels the request everything would tidy itself up nicely, but that in my experience sadly is not the case, if one of the chain decides not to wait, the process that it is waiting for doesn't necessarily know until it tries to send the response back and fails
Come on guys, this is PHP 101. Quoted from the manual:
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.
Execution will stop at the next tickable event after the connection flag is set to ABORTED - which will be detected when PHP attempts to flush output to the client
The current MySQL query will finish executing (as the next event that PHP has control over doesn't occur until after the query has completed), but your script would not make it past that, unless you explicitly set ignore_user_abort. It's always important to account for this when writing code.
There are two ways around this
Set ignore_user_abort to true for the invocation of your script
Do not print anything back to the client until after all of your processing is complete - since a connection closed status won't be detected until output is flushed
Currently I am working on a system in PHP (for syncing data between webservices) (using the Lithium framework) which makes multiple requests to different webservices through curl.
For every response in a request (could be quite some few, lets say 100). However when the client disconnects (e.g. presses stop in the browser) the script continues to running (the log lines keep coming in the log file) 'long' after the client is disconnected.
From what I've read PHP only detects client disconnection when it tries to send output to the browser. So now I am flushing some data after every requests (and every line to the log file) to the browser. But the PHP script continues to run.
I now have the following code after each log call, however this does not seem to work.
//Die on no connection
ignore_user_abort(false);
echo chr(0); flush(); ob_flush();
if(connection_aborted())
{
die();
}
The script just keeps running, it there anything I can do to make sure the script stops after the client (or at least soon after) disconnects?
edit: Why do I always find the solution after posting a question. added 'ob_flush' and that seems to work. Thanks anyways for anyone who has looked into this.
try using ob_flush() instead of flush(), that will flush the output buffer..
I am calling a php script over ajax to do some database maintenance. If the user closes the page, hits back, or clicks a link, will the php script be fully executed? Is there a way to do it?
Maybe if the php script called the exec() method or something similar, which would in turn call a script via the console as such:
$ php /var/www/httpdocs/maintenance.php
?
It's a race condition. PHP will detect at some point (usually upon attempting to do output) that Apache is yelling in its face that the remote user has closed the connection. Whether everything you wanted to do is done at that point depends on how your code's structured.
If you want to ensure that all operations are complete before the script shuts itself down, use ignore_user_abort(TRUE), which keeps PHP running after the connection is severed. It's still subject to the user max_execution_time limits and whatnot, but it will not shut down because you disconnected.
As long as the user agent (browser, etc.) has fully sent the request, the server has all it needs and will complete the request and try to send back a response.
In fact, this sort of "pinging" behavior is often used for "heartbeat"-like processes that keep a service warm or perform periodic maintenance.
Once the web request makes it to your server, it really doesn't matter if the user closes their browser or navigates away. Your server will still respond, but no one will be listening for the response.
Varies on the settings, web server, operating system and so on.
Usually the request will be processed as usual, and the response will just never be read. Occasionally, a write might fail earlier, and the request fails while processing.
Once the ajax call is kicked off, the user is free to do whatever they want. If they close the page they simply won't get the feedback (if any ) from the ajax call that was made.
If the php starts executing then it will continue to execute regardless if the user closes the window or navigates away from the page.
The php script will complete, regardless of browser state. The php is parsed on the server, and that doesn't care about whether the client is still open or not.
If the HTTP request was completed, then yes, the PHP script will be executed fully even if the client's computer is closed.
I've got this PHP script i am starting in my web browser. It reads a lot of data and writes it to a database.
What is happening
when i click BACK in the browser (or go to another link/page)?
close the web browser?
Will the the script run in the background until it's finished?
It should continue running until finished unless the php.ini setting ignore_user_abort is set (disabled by default). Since ignore_user_abort is disabled by default, the default PHP behavior is to terminate the script prior to completion if it detects the user has gone away. To change this, call ignore_user_abort(true); at the beginning of your script.
That said, in somewhat short lived scripts, PHP may not detect the user has gone away until the processing finishes even if the user disconnected several seconds earlier.
See ignore_user_abort() which has an example script that shows it will continue running after the user disconnects.
Also note, PHP will not detect that the user has aborted the connection until an attempt is made to send information to the client. Simply using an echo statement does not guarantee that information is sent, see flush().
If you had started a session, the session file may not be closed (unlocked) until the script finishes running so future page loads by the same user that attempt to start a session may hang until the script with the session lock finishes. To avoid this, you can call session_write_close when session information is no longer needed if you plan on running a script for an extended period of time.
This reference on connection handling in php should also be of interest to you.
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.