FrankenPHP 1.4 Worker 模式无请求结束回调钩子,必须手动将清理逻辑(如 ob_end_clean()、DB::purge()、重置单例、gc_collect_cycles())写在 frankenphp_handle_request() 回调函数末尾。

FrankenPHP 1.4 的 Worker 模式本身不提供类似 register_shutdown_function() 那样的“请求结束回调”钩子机制。它没有内置的、自动触发的、每次请求处理完成后调用的回调注册接口。所谓“请求结束时要做的事”,必须**手动写在你传给 frankenphp_handle_request() 的回调函数末尾**——这是唯一可靠、被明确支持且文档验证过的做法。
必须把清理逻辑写在请求回调函数的最后一行
FrankenPHP 的请求循环结构是:主循环反复调用 frankenphp_handle_request($callback),而 $callback 是你定义的处理单个 HTTP 请求的函数(例如 Laravel 的 public/worker.php 中的匿名函数)。这个回调执行完毕,才代表一次请求真正结束。
因此,所有请求级清理工作——包括重置单例状态、清空输出缓冲、关闭数据库连接、触发垃圾回收——都必须放在该回调函数的最后几行:
-
清空输出缓冲:调用
ob_end_clean()或ob_end_flush() -
释放数据库连接:设
$pdo = null;对 MySQLi 调用$mysqli->close();Laravel 项目加DB::purge() -
重置单例状态:显式调用如
MyService::resetForNextRequest(),清空静态属性和请求上下文 -
强制垃圾回收:紧接在以上操作之后,立即执行
gc_collect_cycles()
不要依赖 register_shutdown_function()
这个函数在 Worker 模式下只在整个进程退出前触发一次,不是每次请求后。实测中它可能完全不执行,或延迟到进程终止时才运行,无法满足请求隔离需求。把它塞进 register_shutdown_function() 等于没做清理。
立即学习“PHP免费学习笔记(深入)”;
别混淆“Worker 进程退出”和“请求结束”
Worker 进程可能因 max_requests 到期、收到 SIGTERM 或主动 break 而退出,但这和单次请求生命周期无关。请求结束的边界非常清晰:就是你那个回调函数执行 return 的那一刻。所有与本次请求相关的资源和状态,必须在此刻完成收尾。
框架集成时注意入口封装
像 Laravel Octane 或 CodeIgniter 4 的 Worker 入口,已经帮你封装了基础回调结构。你需要检查其 worker.php 文件,确认你的自定义服务重置逻辑是否被加在了框架响应发送之后、函数返回之前。如果框架用了中间件链,确保关键清理步骤不在中间件里被跳过或覆盖。



















