frankenphp worker模式是伪常驻,每次请求仍重建运行时环境;swoole才是真常驻,onworkerstart后所有请求共享同一php实例、全局变量、静态属性及连接对象。

FrankenPHP 1.4 的 Worker 模式不是 Swoole 那种真常驻,它只是把 PHP-FPM 的进程池“拉长了一点”,但运行时环境仍按请求重建。
运行时是否跨请求存活
这是最核心的差异:
- Swoole 的 Worker 进程启动后,onWorkerStart 只执行一次,所有后续请求共享同一个 PHP 实例:全局变量、静态属性、Redis/PDO 对象、单例类全部持续存在;
- FrankenPHP Worker 每次调用
frankenphp_handle_request()仍会触发完整的 PHP 请求生命周期(php_request_startup()→php_request_shutdown()),static 属性重置、$GLOBALS 清空、PDO 实例销毁——你 new 的对象不会活到第二个请求。
连接复用能力完全不同
数据库、Redis 等资源能否真正复用,直接决定高并发下的稳定性:
- Swoole 下可在
onWorkerStart中初始化连接池,onRequest直接取用,1000 次请求只建 1 次连接; - FrankenPHP 即使开启
PDO::ATTR_PERSISTENT,也受限于 FPM 进程回收策略(pm.max_requests仍生效),实际连接复用率极低,压测时容易触发 MySQL 连接数耗尽。
内存与状态管理方式不同
怎么存数据、怎么清状态,决定了代码写法是否要大改:
- Swoole 天然支持全局变量、静态类属性跨请求访问,协程间还能共享父作用域变量;
- FrankenPHP 不提供自动状态清理钩子,必须手动
unset大数组、close()显式打开的资源、调用apcu_clear_cache()或重置静态属性; - 它支持 APCu/shmop 做跨请求共享,但仅限可序列化数据,不能存 mysqli/PDO/Redis 资源句柄。
并发模型本质不同
别被“常驻”二字误导,底层调度逻辑完全不是一回事:
- FrankenPHP Worker 是同步阻塞的,一个 Worker 同一时间只能处理一个请求,靠增加 Worker 数量提升并发;
- Swoole 支持协程并发,单个 Worker 内可同时调度数百个协程,I/O 等待时不阻塞,天然适合高并发、低延迟场景;
- FrankenPHP 没有协程调度器,也不支持
Co::sleep()或异步 HTTP 客户端,想并发只能靠curl_multi或起子进程。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











