必须在Caddyfile的php块内显式配置worker指令,否则FrankenPHP始终运行于per-request模式;即使使用public/worker.php入口,缺少worker指令也不会启用常驻模式。

必须在 Caddyfile 中显式写 worker 指令,否则永远是 per-request 模式,哪怕入口文件叫 worker.php 也没用。
php 块里漏掉 worker 就等于没开
FrankenPHP 默认不启用 worker 模式,php 指令本身只表示“交给 PHP 处理”,和传统 CGI 行为一致。要激活常驻模式,必须在 php 块内部加 worker 子指令:
localhost {
route {
php {
root /var/www/myapp/public
worker
}
}
}
-
worker必须出现在php { ... }块内,不能放在外面或嵌套在其他指令下 - 不支持
worker off或条件开关;有这行就启用,没这行就是普通模式 - 如果同时用了
php_server,它会忽略worker——php_server是 FastCGI 兼容层,和 worker 模式互斥
worker 后要不要指定入口文件?
可以不写,但强烈建议显式指定,避免歧义:
php {
root /var/www/myapp/public
worker /var/www/myapp/public/worker.php
}
- 路径必须是绝对路径;
./public/worker.php或worker.php会失败(Caddy 启动时工作目录不可控) - 别用
index.php当 worker 入口:它没做请求循环封装,会导致Class 'App\Kernel' not found或卡死在frankenphp_busy_threads = 1 - Symfony 6.3+ 自带
public/worker.php;ThinkPHP/CodeIgniter 等需按官方模板手动创建,核心是用frankenphp_handle_request()包裹请求逻辑
配了 worker 却没生效?先看这三个地方
常见假性启用:日志没报错、服务能访问,但实际仍是每次新建进程。
立即学习“PHP免费学习笔记(深入)”;
- 检查 Caddy 日志是否出现
Starting PHP worker pool with X workers—— 没这句说明根本没走 worker 流程 - 在控制器里打
getmypid(),连续两个请求 PID 相同才代表成功复用;不同 PID 就是 fallback 到 per-request - 确认没在环境变量里设
FRANKENPHP_WORKER=0或APP_ENV=dev(某些框架 dev 模式会禁用 worker 入口)
最易被忽略的一点:worker 指令只是“启动开关”,真正决定能否稳定运行的,是入口文件里有没有正确调用 frankenphp_handle_request() 并做状态重置——没这一步,复用的只是进程,不是干净的请求上下文。



















