停掉所有worker进程并改启动方式才能切回经典模式:先执行frankenphp stop-workers优雅退出worker,再移除caddyfile中php { worker ... }配置、取消frankenphp_worker=1环境变量,确保启动日志显示“starting frankenphp server”而非“worker server”,并清除opcache及框架缓存。

停掉所有 worker 进程再改启动方式
FrankenPHP 没有“动态切换模式”的机制,Worker 模式和经典模式是互斥的启动状态。切回经典模式的本质是:让当前所有常驻 worker 退出,然后用不带 worker 配置的方式重新启动。
常见错误是只改配置但没清 worker,结果新进程起不来、旧 worker 还在处理请求,造成行为混乱。
- 执行
frankenphp stop-workers—— 这会向所有活跃 worker 发送优雅退出信号(完成当前请求后终止),不是 kill,不会中断正在跑的请求 - 确认没有残留进程:
ps aux | grep 'frankenphp.*worker',若还有,说明stop-workers没生效,大概率是没设FRANKENPHP_WORKER=1或路径不对导致 worker 启动失败,此时实际根本没进 Worker 模式 - 删掉 Caddyfile 中的
php { worker ... }块,或注释掉;命令行启动时去掉--worker参数 - 确保环境变量
FRANKENPHP_WORKER未设置(unset FRANKENPHP_WORKER或启动时不传),否则即使 Caddyfile 没写 worker,它也会尝试加载并静默失败
检查终端输出确认是否真退回经典模式
FrankenPHP 启动时第一行日志就是模式标识,这是唯一可靠判断依据。很多人以为配置改了就切过去了,结果终端还印着 Starting FrankenPHP Worker Server,说明 Octane 或 worker 脚本仍在被调用。
- 正确退回后,终端首行必须是
Starting FrankenPHP Server(注意没有Worker字样) - 如果看到
Starting FrankenPHP Worker Server,立刻检查:vendor/bin/frankenphp-worker.php是否存在、是否可执行、config/octane.php中'server'键值是否拼错(比如写成'frankenphp '多了个空格) - 经典模式下不需要
composer require laravel/octane,也不需要php artisan octane:install;这些包留着无害,但只要它们的启动器被触发,就会拉起 worker
经典模式下 public/index.php 不再被 worker 封装
Worker 模式会绕过原始入口,用 frankenphp-worker.php 加载框架并循环调用 frankenphp_handle_request()。切回经典模式后,FrankenPHP 回归 FastCGI 语义:每次请求都完整执行一遍 public/index.php,就像 PHP-FPM 那样。
- 你之前为 Worker 模式加的
ignore_user_abort(true)、gc_collect_cycles()、$app->resetResolvedInstances()等清理逻辑,现在全部失效且没必要——PHP 生命周期自然结束,变量自动销毁 - 如果入口文件里还保留着
frankenphp_handle_request()包裹,会导致经典模式下报错:Call to undefined function frankenphp_handle_request(),因为该函数只在 worker 运行时注入 - 无需重装扩展或改
.env,经典模式对代码零侵入,Laravel/Symfony 的public/index.php原样可用
OPcache 和配置缓存要手动清一次
从 Worker 切回经典模式本身不触发任何缓存刷新,但旧 worker 进程可能已把大量 PHP 文件、路由、配置缓存在内存里。哪怕你已经停掉 worker,OPcache 仍可能服务旧字节码,Laravel 的 config:cache 和 route:cache 也还是旧版本。
- 执行
php artisan config:clear && php artisan route:clear && php artisan view:clear(Laravel)或对应框架的缓存清除命令 - 重启 FrankenPHP 前,加一句
opcache_reset()到临时脚本里执行,或直接在 PHP 配置中设opcache.enable_cli=1后运行php -r "opcache_reset();" - Redis 缓存(如 Laravel 的
cache:clear)也要清,否则中间件或策略类可能读到旧逻辑
最容易被忽略的是:你以为切回经典模式就“安全了”,但 OPcache 里的旧 index.php 还在响应请求,直到缓存自然过期或被强制重置。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











