FrankenPHP 1.0 的 Worker 模式需显式指定绝对路径的 --script 和 --addr,入口脚本须分三层结构、手动管理生命周期、预置环境变量,否则降级为普通请求模式。

FrankenPHP 1.0 的 Worker 模式不是默认开启的,也不能靠简单加个 --worker 就生效。它依赖明确的启动方式、正确的入口结构和环境准备,否则进程会闪退或降级为普通请求模式。
必须显式指定 --script 绝对路径
frankenphp-worker 命令本身只是一个可执行入口,不自动启用 Worker 模式。真正触发常驻行为的是 --script 参数:
- ✅ 正确写法:
./frankenphp-worker --script /app/public/worker.php --addr :8080
- ❌ 常见错误:
-
--script public/worker.php(相对路径 → 启动失败) -
--script ./public/worker.php(当前目录不可靠,解析失败) - 漏掉
--script→ 直接报错flag needs an argument: --script
-
--addr也必须显式指定,否则监听端口可能冲突或行为不确定。
入口脚本 worker.php 必须分三层写
不能直接把 index.php 改名复用。Worker 模式下 PHP 进程长期运行,必须手动控制生命周期:
立即学习“PHP免费学习笔记(深入)”;
-
循环外(初始化一次)
- 加载自动加载器:
require_once __DIR__.'/../vendor/autoload.php'; - 创建并启动 Kernel:
$kernel = new Kernel($_ENV['APP_ENV'], (bool) $_ENV['APP_DEBUG']); $kernel->boot();
- 加载自动加载器:
-
循环内(每次请求执行)
- 用
frankenphp_handle_request()包裹请求处理逻辑:frankenphp_handle_request(function () use ($kernel) { $request = \Symfony\Component\HttpFoundation\Request::createFromGlobals(); $response = $kernel->handle($request); $response->send(); $kernel->terminate($request, $response); });
- 用
-
每次请求后(清理)
- 手动触发垃圾回收:
gc_collect_cycles(); - 重置关键超全局变量(如
$_SERVER['REQUEST_URI']),避免残留影响下一次请求
- 手动触发垃圾回收:
环境变量必须提前注入,不能靠 .env 动态读
独立二进制打包后,.env 文件通常不包含在内,且 Dotenv::createUnsafeImmutable() 在常驻进程中只运行一次。
- ✅ 正确做法:启动前通过系统环境变量传入
APP_ENV=prod APP_DEBUG=0 ./frankenphp-worker --script /app/public/worker.php --addr :8080
- ❌ 错误做法:在
worker.php里调用Dotenv::create()->load()—— 第二次请求会失效,导致APP_ENV变成空或默认值
验证是否成功进入 Worker 模式
- 查看日志是否有类似输出:
Starting PHP worker pool with 1 workers - 发起两个请求,在控制器中打印
getmypid():- 如果 PID 相同 → 成功常驻
- 如果 PID 不同 → 仍是 per-request 模式
不复杂但容易忽略



















