PHP Conference Japan 2024

fastcgi_finish_request

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

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

描述

fastcgi_finish_request(): bool

此函数将所有响应数据刷新到客户端并结束请求。这允许执行耗时的任务,而不会保持与客户端的连接打开。

参数

此函数没有参数。

返回值

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

添加注释

用户贡献的注释 3 条注释

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

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

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

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

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

第一个是基本示例。

<?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
10 个月前
[email protected] 认定此 https://bugs.php.net/bug.php?id=68772 为“不是错误”,但是请注意

如果您在调用 `fastcgi_finish_request()` 后写入缓冲区(使用 print 语句等),您的脚本将退出,不会显示任何错误消息或异常。在 `fastcgi_finish_request()` 后调用 `ignore_user_abort(true)` 可以缓解此问题。
To Top