symfony项目需适配frankenphp:①确保public/index.php为标准入口、php≥8.1、symfony/runtime≥6.3;②通过caddyfile worker指令或frankenphp_worker=1启用;③修改bootstrap.php禁用exit、移除index.php中kernel实例化、末尾调用frankenphp_set_worker_ready();④验证响应头含x-powered-by: frankenphp/worker且二次请求明显加速。

确认项目已适配FrankenPHP运行环境
你的Symfony项目必须能被FrankenPHP识别为可常驻的PHP应用,否则worker模式启动即失败。
检查public/index.php是否保留了标准的require引导入口——FrankenPHP worker模式依赖此文件作为PHP进程的唯一启动点,不能替换成index.php中直接输出内容或提前exit。
运行php -v确认PHP版本在8.1及以上,FrankenPHP官方要求【最低PHP 8.1】,低于该版本会静默跳过worker初始化。
确保composer.json中"symfony/runtime"已安装且版本≥6.3,旧版Runtime组件不兼容FrankenPHP的生命周期钩子。
启用FrankenPHP Worker模式的两种方式
方法一:通过Caddyfile声明worker指令(推荐用于生产)
在项目根目录创建或编辑Caddyfile,写入以下内容:
localhost:8000 {
php_server {
worker /var/www/symfony/public/index.php
}
encode zstd gzip
}
注意:worker指令后的路径必须是绝对路径,相对路径会导致FrankenPHP无法定位入口文件而报错failed to load worker script。
方法二:通过环境变量临时启用(适合本地调试)
执行:FRANKENPHP_WORKER=1 ./frankenphp run --caddyfile Caddyfile
这一步不需要改任何配置文件,但仅对当前命令生效;关闭终端后失效。
修改Symfony以支持常驻生命周期
第一步:禁用默认的CLI自动终止机制
打开config/bootstrap.php,在if (PHP_SAPI === 'cli')判断块内,添加return;提前退出——否则Symfony会在每次请求后主动调用exit(),导致worker进程被强制杀死。
第二步:将Kernel实例化逻辑移出public/index.php
原index.php中类似$kernel = new Kernel($_SERVER['APP_ENV'], (bool) $_SERVER['APP_DEBUG']);这一行必须删除,改由FrankenPHP内部按需创建;否则多个请求会反复new Kernel,引发服务容器状态污染。
第三步:显式注册worker就绪回调(关键)
在public/index.php末尾追加:
if (function_exists('frankenphp_set_worker_ready')) {
frankenphp_set_worker_ready();
}
这一步【不可省略】,否则FrankenPHP认为worker尚未准备就绪,会持续拒绝分发请求,日志中出现worker not ready但无其他报错。
启动并验证Worker模式是否生效
执行:./frankenphp run --caddyfile Caddyfile
访问http://localhost:8000,查看响应头中是否存在X-Powered-By: FrankenPHP/worker字段。
用curl发起两次请求并观察响应时间差异:curl -w "\n%{time_total}s\n" -o /dev/null -s http://localhost:8000
若第二次请求耗时比第一次低30ms以上,说明框架初始化已被复用,worker模式已实际生效。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











