FrankenPHP 1.1开启Worker模式需显式声明worker脚本路径并改造入口逻辑:用frankenphp_handle_request包裹请求处理,循环外初始化框架,循环内重置状态、清理连接、触发GC,避免静态变量污染。

在 FrankenPHP 1.1 中开启 Worker 模式,核心是让 PHP 应用常驻内存、复用初始化环境,而不是每次请求都重新加载框架。但开启后若未正确处理生命周期,容易出现请求残留(比如上一个请求的 session、全局变量、数据库连接未清理,影响下一个请求),这是 Worker 模式下最典型的“状态污染”问题。
确认并启用 Worker 模式
FrankenPHP 1.1 不再依赖外部配置开关,而是通过启动参数或 Caddyfile 显式声明 worker 脚本路径:
- 命令行方式:运行
frankenphp php-server --worker ./public/index.php(路径需指向你的实际入口文件) - Caddyfile 方式:在路由块中使用
php { worker ./public/index.php },确保该路径可被 FrankenPHP 进程读取 - Docker 环境下,通过环境变量
FRANKENPHP_CONFIG="worker ./public/index.php"传入
修改入口脚本以适配 Worker 生命周期
普通 PHP-FPM 入口是“一次请求、一次执行”,而 Worker 模式要求你手动控制循环和清理。必须用 frankenphp_handle_request() 包裹业务逻辑,并在每次请求后主动释放资源:
- 入口文件开头加
ignore_user_abort(true);防止客户端断连中断 worker - 将框架初始化(如 Laravel 的
$app = require_once __DIR__.'/bootstrap/app.php';)放在循环外,只执行一次 - 将请求处理逻辑(如
$response = $kernel->handle($request))放入frankenphp_handle_request()的回调中 - 每次回调执行完后,显式调用
gc_collect_cycles();触发垃圾回收 - 避免在循环外缓存用户态数据(如
static $userCache = [];),这类变量会在多次请求间持续存在
解决请求残留的关键操作
残留问题本质是“状态未隔离”。FrankenPHP 不会自动帮你重置 PHP 运行时上下文,你需要主动干预:
立即学习“PHP免费学习笔记(深入)”;
-
清空超全局变量残留:在每次请求处理前,重置
$_GET、$_POST、$_SERVER['REQUEST_URI']等(FrankenPHP 已做基础重置,但自定义中间件可能绕过) -
重置框架级状态:Laravel 用户应在每次请求后调用
$app->resetResolvedInstances();和$app->forgetInstance('request');;ThinkPHP 可调用think\Container::clear(); -
关闭/复用数据库连接:禁用持久连接(
PDO::ATTR_PERSISTENT => false),或在请求结束时显式调用DB::disconnect()(Laravel)或Db::close()(TP6) -
避免静态属性跨请求污染:检查模型、服务类中是否误用
static $data存储请求相关数据,改用依赖注入或 request scope 实例
验证与调试建议
Worker 是否生效、残留是否已控,可通过以下方式确认:
- 访问
http://localhost:2019/metrics(admin 端点),查看frankenphp_worker_requests_total{worker="index.php"}是否持续增长,且frankenphp_worker_queue_length基本为 0 - 在入口回调中临时加入
error_log('Request ID: ' . uniqid());,观察日志中 ID 是否连续生成(说明复用进程),而非每次重启进程 - 构造两个带不同参数的并发请求,检查响应中是否混入前一个请求的 session 数据或缓存结果



















