This article brings you the content is about PHP fastcgi_finish_request introduction and implementation of non-blocking code, there is a certain reference value, the need for friends can refer to, I hope to help you.
Objective
In the actual project often have this demand, for the front end of the request, need to be in the backend for a long time processing, but in order to let the user have a better experience, in order to let PHP in the back-end processing long-time tasks without blocking, quickly respond to page requests, so here to Fastcgi_finish_ The application of request is summarized and summed up. Of course, there are many ways to implement non-blocking PHP, such as asynchronous script, Swoole, but personally think Fastcgi_finish_request is the most simple and convenient.
Basic applications
Fastcgi_finish_request Introduction
(PHP 5 >= 5.3.3, PHP 7)
fastcgi_finish_request-Flushing (flush) All the response data to the client
Boolean fastcgi_finish_request (void)
This function flushes (flush) all the response data to the client and ends the request. This allows a task that requires a large amount of time to run after the client ends the connection.
return value
Returns TRUE on success, or FALSE on failure
Attention issues
PHP and the WEB server use the PHP-FPM (fastcgi process Manager), which can end the session immediately through the Fastcgi_finish_request () function, while the PHP thread can continue to run in the background. That is, only for PHP-FPM process management to use this function
As soon as the code runs to this location, the request is dropped and the parameter is returned to the client. The next code is not related to the client. That is, the output must be placed before the Fastcgi_finish_request function in the page's contents.
Fastcgi_finish_request () After the client connection is completed, the run time is still affected by the max_execution_time time-out time, that is, if the code is expected to take longer to execute on the back end, set the Set_time_limit ( 0)
In high concurrency execution time too long will cause the fastcgi process is not enough, can not be released in time, will explode 502 error.
Application
echo "program start ..."; File_put_contents ('/tmp/garylog.log ', ' start-time: '. Date (' y-m-d h:i:s '). " \ n ", file_append); Fastcgi_finish_request (); sleep (1);//Set_time_limit (0);//Sleep (), $num = +, $num + = 1;sleep (5); echo ' Debug ... '; file_put_contents ('/tmp/garylog.log ', ' start-proceed: '. $num. ', Time '. Date (' y-m-d h:i:s '). " \ n ", File_append), Sleep (file_put_contents) ('/tmp/garylog.log ', ' end-time: '. Date (' y-m-d h:i:s ')." \ n ", file_append);
Run Tests
Compatible with non-PHP-FPM
From the code portability, you can include the following code in your code:
if (!function_exists ("Fastcgi_finish_request")) { function fastcgi_finish_request () { } }
Does not cause code deployment to cause problems in non-FPM environments.
Guaranteed Process Single operation
For the above-mentioned problem: In high concurrency execution time too long will lead to fastcgi process is not enough, can not be released in time. At the same time our demand is only to play the role of triggering, do not need to run each time, then consider using the following method, to avoid the duplication of the process.
$processId = Realpath (__file__). '-' . Get_class ($this); $filename = MD5 ($processId); $file = '/tmp/' $filename; if (!file_exists ($filename)) { File_put_ Contents ($file, Getmypid ());} else{ return true;} # # Do somthing takes a long time to process the code//processing completes after deleting the process ID record file unlink ($file);