fastcgi_finish_request

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

fastcgi_finish_request将所有响应数据刷新到客户端

说明

fastcgi_finish_request(): bool

此函数将所有响应数据刷新到客户端并完成请求。这允许在不保持与客户端的连接打开的情况下执行耗时的任务。

参数

此函数没有参数。

返回值

成功时返回 true,失败时返回 false

添加注释

用户贡献的注释 4 个注释

tuxrampage
8 年前
使用此函数时,您应该注意一些陷阱。

在 fastcgi_finish_request() 之后,脚本仍将占用 FPM 进程。因此,过度使用它执行长时间运行的任务可能会占用所有 FPM 线程,直到 pm.max_children。这会导致 Web 服务器出现网关错误。

另一件重要的事情是会话处理。会话在活动时处于锁定状态(请参阅 session_write_close() 的文档)。这意味着后续请求将被阻塞,直到会话关闭。

因此,您应该尽快调用 session_write_close()(甚至在 fastcgi_finish_request() 之前),以允许后续请求并提供良好的用户体验。

这也适用于所有其他锁定技术,例如 flock 或数据库锁。只要锁处于活动状态,后续请求可能会阻塞。
rundiz dot com
2 年前
以下是一些使用它的示例。

第一个是基本示例。

<?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);
?>

如果成功,将创建文件 text.txt。

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

第二个是关于执行超时。

<?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...
}
?>

我发现,只要没有达到 php.ini 或 set_time_limit() 函数中设置的超时时间,代码就会继续运行。
john at jrcii dot com
7 个月前
[email protected] 认为这是 https://bugs.php.net/bug.php?id=68772 “不是错误”,但请注意

如果您在调用 fastcgi_finish_request() 后写入缓冲区(使用 print 语句等),您的脚本将退出,不会显示任何错误消息或异常。在 fastcgi_finish_request() 后调用 ignore_user_abort(true) 可以缓解此问题。
Patrick Allaert
3 年前
这是异步执行的非常简陋的方法。

最好依赖消息队列来异步处理某些内容。
To Top