HTTP request and PHP process - php

I have an action that occurs when a user goes to a url. The action involves a tremendous amount of insert-update ot a MYSQL database and takes a good minute to finish. I was wondering if this action continues even if a user switches to another page? I would expect so since PHP is server side. But i would like to have a clear explanation on this. Anyone?

No, the default operation of Apache and PHP is to terminate the script when the user disconnects. This termination can happen anytime after the connection is broken, so your script may run for hours, or could die instantly. Generally the kill occurs when the script attempts to do any output.
If you need to keep the script running in spite of user disconnects, then you'll have to use
ignore_user_abort(TRUE);

Related

Laravel generate PDF process still ongoing even after browser closed or process failed [duplicate]

Say a user clicked a button, which resulted in a jquery ajax request being sent to my server.
The server begins a complicated process in response to the ajax request. Lets say that process takes 5 minutes to finish.
In the meantime the user gets bored and closes his browser window.
Will the script on the server continue its processing until it finishes on its normal time, or will it stop?
Same thing if the user visits a url, e.g example.com/process.php?data=xxx. This starts process.php which begins to process the data, and will take 5 mins to finish processing.
Will this processing always continue on, or if the user closes the browser, will it stop?
(I'm asking because I'm concerned about the process being left half finished and resulting in corrupt data).
PHP won't notice that the browser closed the connection unless it tries to output something (e.g. echo). If it fails to output something, the script will be terminated unless ignore_user_abort is On.
So the script will terminate only if the following conditions are met:
the script attempts to output something (because the script won't notice that the user aborted the connection until then)
AND php's ignore_user_abort setting is off (if the setting is off, php will terminate the script if fails to output something)
You can avoid the script from terminating by enabling ignore_user_abort.
You can use connection_aborted() at anytime to check is the browser aborted the request.
A script can terminate unexpectedly for other reasons (e.g. max execution time, exception, etc); so you should make use of transactions, so that half-finished changes are canceled if the script terminates abnormally.
See: http://php.net/manual/en/function.ignore-user-abort.php. It depends on the ignore_user_abort setting and a few other conditions.
The default behaviour for PHP is that your script will be aborted when the remote client disconnects, usually caused by a user closing their browser or hitting the stop button. It can also happen when someone closes a remote connection to a script run in CLI mode. The one exception to your script aborting is if you have registered a shutdown function using register_shutdown_function(). For a thorough explanation please see the Connection Handling page in PHP docs.
The point at which the script actually terminates is dependent upon when flush() is called, which essentially attempts to push current output all the way to the browser/client. At this point if the state of the connection is ABORTED then the script will terminate, unless we are ignoring user abort.
The important thing to note is that you can control whether this behaviour occurs or not, as you specify sometimes it is undesirable for this to happen. Using the ignore_user_abort() function or setting the associated directive in php.ini.
Unless it's launched as a background process i.e. with the & at the end... it will just terminate.
Closing browser a bit more to it... It will stop eventually, but will process for a little while before web server realises connection is gone.

php code canot stop after user abort, it runs until the script is completed

I am writing a website with php and there is a part of code need huge amount of time to execute.
Since I don't use thread, when I run that code, the whole server is blocked by it. But it's OK.
Hovever, even though I closed that web page, it still executes and blocked my server. I cannot access any page of my website until the process completed.
Since the execution time is very long, so that I set a very long set_time_limit() for it but I don't set ignore_user_abort so that I supposes that it should not run after user abort. Or is it the problem of curl(the code does many curl job)?
Can someone tell me that why the php script cannot stop when the user close the connection? Or there are some way to assure the script can be stopped when user abort?
Thanks.
Closing the browser doesn't tell the server to stop doing something. It doesn't tell the server anything.
Long-running processes don't belong in web applications. Generally you would want some background task to handle the process. Either the web application would spawn this task (this seems like a workable approach) or would in some way queue the processing of this task where a background worker would see that queue (such as a database table polled every X minutes by a daemon process).
The goal is to not block the UI while the task is running. Even if the user were to leave the browser open, the browser itself may "give up" after a while or something else could sever the user from the UX while waiting for too long. Let the user invoke the process, but separate the invocation of the process from the execution of the process so the user can return to the application interface.
From the PHP Manual:
PHP will not detect that the user has aborted the connection until an
attempt is made to send information to the client.
Thus, even using ignore user abort, you must try to interact with the client again inside the script to ensure it aborts correctly. Note that on the page in question there are some additional notes about what constitutes 'sending information' (for example, an Echo doesn't qualify by itself, apparently).
Further Reading:
http://php.net/manual/en/function.ignore-user-abort.php

What happens to canceled requests to a PHP page?

When a long-running PHP file is executing, and the user cancels the page request in their browser midway, is the rest of the script ran on the server?
PHP normally terminates script execution once it realizes that the connection is closed:
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().
You can keep your script running using ignore_user_abort().
Also, there is a default time limit for which scripts are allowed to run. You may want to override that using set_time_limit().
I tested this once on a long running process and discovered that the script will continue to run once it has not exceeded the maximum time to execute.
For me (using XAMPP on an older computer), cancelling the web page in the middle of an operation meant to process one million primary records, with a couple of other tables being updated in the process, the MySQL database operations kept going, which tells me that the PHP script kept running on the server. By "cancelling," I mean clicking the stop button on the tab, but not closing the tab altogether. BTW: I had established set_time_limit() to 0 to keep the script from timing out before completing in absence of cancelling.

PHP script aborts, causes MySQL transaction to fail, whole app locks for a little while

I'm using transactions in a MySQL database, along with Ajax, and I'm having some troubles with scripts timing out. So, here's a rundown of what happens:
Ajax script on page makes request to server.
Server receives request; script starts a MySQL transaction.
Ajax script is set to timeout after two seconds; times out; tells server to abort request.
Server script dies; transaction is left hanging.
MySQL notices transaction has been left hanging; rolls back as it's supposed to, but not before a bunch of customers become less than happy because the tables were locked for half a minute and they couldn't access the website.
What to do?
I imagine the server script just needs a bit more time than the two seconds it's given, so I called ignore_user_abort() on every page, and then called register_shutdown_function() to explicitly roll back a transaction if the client has in fact aborted.
Is this a good plan? Is there an alternative?
register_shutdown_function() by itself would even be a good solution. Try removing the ignore_user_abort() so that the script knows when (or if) the users aborts the loading.
I would also probably let the script have more than 2 seconds of a time out, see if this helps.
Are you using persistent database connections, ie: using mysql_pconnect()? Those will keep the connection alive within the web server even when no PHP script is running. As such, any transactions/locks acquired during the script's run will be left active within that persistent connection when the script shuts down abnormally.
Even if your scripts normally clean up after themselves with mysql_close(), any abnormal termination will leave that persistent connection up. And stay up until the connection is re-used from the pool and properly shut down by some other script.

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