FrankenPHP 不直接提供 PHP 脚本级长连接,但通过 Caddy 支持 HTTP keep-alive 与 HTTP/3、Worker 模式实现应用层资源复用、兼容标准持久连接(PDO/Redis/MySQLi),并支持 Go 扩展构建自定义 TCP/UDP 长连接服务。

FrankenPHP 本身不直接提供“PHP 脚本级长连接”(如 WebSocket 或自定义 TCP 长连接服务)的开箱即用抽象,但它天然支持并默认启用 HTTP 层的长连接(HTTP keep-alive)和 HTTP/3 连接复用,同时通过其 worker 模式让 PHP 代码常驻内存,间接实现了应用逻辑层的“连接保持能力”。
更关键的是:它为开发者提供了构建真正长连接服务的底层基础——比如用 Go 编写扩展处理持久 TCP 连接、或在 PHP 中复用数据库/Redis 等客户端的持久连接池。
以下是具体支持维度与启用方式:
HTTP 层长连接(keep-alive 与 HTTP/3)
FrankenPHP 基于 Caddy,而 Caddy 默认开启 HTTP/1.1 keep-alive 和 HTTP/2 多路复用。只需启用 HTTP/3,就能获得更低延迟、连接复用更强的传输层能力:
立即学习“PHP免费学习笔记(深入)”;
-
在
Caddyfile全局块中添加:{ servers { protocol { experimental_http3 } } frankenphp { num_threads 4 } } -
验证是否生效:
curl -I https://yourdomain.com --http3
若响应头含
alt-svc: h3=":443"; ma=86400,说明 HTTP/3 已就绪,连接可自动复用、减少握手开销。
PHP 应用层“伪长连接”:Worker 模式
这是 FrankenPHP 区别于传统 FPM 的核心优势。开启后,PHP 脚本不会随每次请求销毁,而是常驻内存,框架初始化、数据库连接、缓存客户端等资源可跨请求复用:
-
启用方式(在
Caddyfile中):yourdomain.com { php_server { worker } } -
效果:
- Laravel/Symfony 的容器、配置、服务提供者只初始化一次;
- 可在
bootstrap/app.php或中间件中复用 PDO 或 Redis 连接(需显式设置PDO::ATTR_PERSISTENT => true或使用predis/predis的连接池); - 避免每请求重复加载
.env、扫描类、注册事件监听器等高开销操作。
数据库等外部服务的持久连接
FrankenPHP 不干涉 PHP 扩展行为,因此标准的持久连接机制完全可用:
- MySQLi:使用
mysqli_pconnect()或设置MYSQLI_CLIENT_COMPRESS | MYSQLI_CLIENT_FOUND_ROWS(注意:pconnect在 worker 模式下效果更明显); - PDO:构造时传入选项:
$pdo = new PDO($dsn, $user, $pass, [ PDO::ATTR_PERSISTENT => true, PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, ]); - Redis(Predis):启用连接池或复用
Predis\Client实例(worker 生命周期内单例即可)。
自定义长连接服务(如 TCP/UDP 服务器)
FrankenPHP 允许你用 Go 编写扩展,接管底层 socket。例如:
- 在 Go 扩展中启动一个 goroutine 监听端口;
- 使用
mmap或 channel 与 PHP 主线程通信; - PHP 侧通过自定义函数触发连接管理(如
my_tcp_connect(),my_tcp_send());
这适合做内部 RPC、设备心跳、实时消息代理等场景,但需自行处理连接生命周期与并发安全。
- 关键前提:
- Go 项目启用 CGO;
- 编译为
.so扩展并加载到 FrankenPHP; - 注意内存隔离与错误传播(PHP 异常不能穿透到 Go goroutine)。
不复杂但容易忽略



















