fastcgi_finish_request

(PHP 5 >= 5.3.3, PHP 7, PHP 8)

fastcgi_finish_request冲刷(flush)所有响应的数据给客户端

说明

fastcgi_finish_request(): bool

此函数冲刷(flush)所有响应的数据给客户端并结束请求。这允许在不打开与客户端之间的连接的情况下执行耗时任务。

参数

此函数没有参数。

返回值

成功时返回 true, 或者在失败时返回 false

add a note add a note

User Contributed Notes 4 notes

up
88
tuxrampage
8 years ago
There are some pitfalls  you should be aware of when using this function.

The script will still occupy a FPM process after fastcgi_finish_request(). So using it excessively for long running tasks may occupy all your FPM threads up to pm.max_children. This will lead to gateway errors on the webserver.

Another important thing is session handling. Sessions are locked as long as they're active (see the documentation for session_write_close()). This means subsequent requests will block until the session is closed.

You should therefore call session_write_close() as soon as possible (even before fastcgi_finish_request()) to allow subsequent requests and a good user experience.

This also applies for all other locking techniques as flock or database locks for example. As long as a lock is active subsequent requests might bock.
up
12
rundiz dot com
3 years ago
Here are few example of how to using it.

The first is basic example.

<?php
$file
= __DIR__ . '/text.txt';

if (
is_file($file) && is_writable($file)) {
    @
unlink($file);
    echo
'<small style="color: #ccc;">' . $file . ' was deleted.</small><br>' . PHP_EOL;
}

echo
'<p>Calling to <code>fastcgi_finish_request()</code>.</p>' . PHP_EOL;

echo
'<p>If success, the file ' . $file . ' will be created.</p>' . PHP_EOL;

if (
function_exists('fastcgi_finish_request')) {
   
fastcgi_finish_request();
} else {
    echo
'<p style="color: red;">This server does not support <code>fastcgi_finish_request()</code> function.</p>' . PHP_EOL;
    echo
'Exit now.<br>' . PHP_EOL;
    exit();
}

echo
'This line will be not echo out.<br>' . PHP_EOL;

file_put_contents($file, date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
?>

The file text.txt will be create if successfully.

==========================

The second is about execution timeout.

<?php
set_time_limit
(5);

$file = __DIR__ . '/text.txt';

if (
is_file($file) && is_writable($file)) {
    @
unlink($file);
    echo
'<small style="color: #ccc;">' . $file . ' was deleted.</small><br>' . PHP_EOL;
}

echo
'<p>Testing timeout and <code>fastcgi_finish_request()</code> function.</p>' . PHP_EOL;

echo
'<p>Set timeout to ' . ini_get('max_execution_time') . ' seconds.</p>' . PHP_EOL;

echo
'<p>Calling to <code>fastcgi_finish_request()</code>.</p>' . PHP_EOL;

echo
'<p>If success, the file ' . $file . ' will be created but error will be shown in the log.</p>' . PHP_EOL;

if (
function_exists('fastcgi_finish_request')) {
   
fastcgi_finish_request();
} else {
    echo
'<p style="color: red;">This server does not support <code>fastcgi_finish_request()</code> function.</p>' . PHP_EOL;
    echo
'Exit now.<br>' . PHP_EOL;
    exit();
}

$i = 1;
while(
true){
    if (
$i <= 10) {
       
file_put_contents($file, date('Y-m-d H:i:s') . PHP_EOL, FILE_APPEND);
       
$i++;
    }
   
//to infinity and beyond...
}
?>

I found that the code will be working as long as it is not reach timeout setting in php.ini or set_time_limit() function.
up
1
john at jrcii dot com
10 months ago
mike@php.net decided this https://bugs.php.net/bug.php?id=68772 is "not a bug" however be warned:

If you write to the buffer (using print statements, etc.) after calling fastcgi_finish_request(), your script will exit with no error message or exception. Calling ignore_user_abort(true) after fastcgi_finish_request() can mitigate this issue.
up
-28
Patrick Allaert
3 years ago
This is very poor man's approach to async execution.

Better relying on message queues to process something asynchronously.
To Top