FrankenPHP 本身不提供 publish 或 update 函数,它只是嵌入式 PHP 应用服务器,所有“发布更新”逻辑需在应用层自行实现,如清 OPcache、重载配置、写日志等。

FrankenPHP 里没有 publish 或 update 函数
FrankenPHP 不是 CMS 或框架,它本身不提供“发布更新”这类业务逻辑接口。你在 PHP 代码中想“发布更新”,实际指的是:触发应用层的某项操作(比如刷新缓存、重载配置、通知前端有新版本、写入更新日志等)。这些动作和 FrankenPHP 无关,得靠你自己实现。
FrankenPHP 的角色只是以 SAPI 方式运行 PHP —— 它把 PHP 当作嵌入式引擎跑在 Go 进程里,所以你写的 PHP 代码行为和在 Apache/FPM 下几乎一致,只是启动方式、信号处理、生命周期略有不同。
如何在 FrankenPHP 中安全地触发 PHP 层的更新动作
常见场景包括:管理员点击“上线新配置”、CI 部署后自动刷新路由缓存、或定时检查并加载新版 JSON 配置。关键点在于:FrankenPHP 默认启用 opcache.preload 和长生命周期,直接改文件可能不生效,必须主动干预。
- 用
opcache_reset()清除预加载的字节码(但注意:FrankenPHP 的 preload 是进程级的,调用后只影响当前 worker,不是全局) - 避免在请求中直接
file_put_contents()写核心配置,除非你确认该文件不会被 opcache 缓存(加opcache.enable=0或设opcache.file_update_protection=0并配合opcache_invalidate()) - 推荐用信号 + PHP-FPM 风格的 reload 机制:通过
kill -USR2 $(cat /var/run/frankenphp.pid)重启 worker,但需提前在frankenphp.yaml中配置pid_file - 更轻量的做法是用 Redis 或 APCu 做“更新标记”,让各请求先查
apcu_fetch('app_version')再决定是否重新初始化服务类
frankenphp.SymfonyRequest 和更新逻辑无关
有人看到文档里有 frankenphp.SymfonyRequest 就以为能用它发“更新指令”,其实这是个用于桥接 Symfony HTTP Kernel 的底层封装,只负责把 Go 的 request 映射成 Symfony\Component\HttpFoundation\Request 实例。它不提供网络调用、事件广播或部署能力。
立即学习“PHP免费学习笔记(深入)”;
如果你真需要从 PHP 内部触发外部更新(比如调用部署 API),就老实用 file_get_contents()、curl_init() 或 Symfony\Contracts\HttpClient\HttpClientInterface —— 和在 FPM 下完全一样,FrankenPHP 不拦截也不增强这些函数。
容易忽略的 FrankenPHP 特性:worker 生命周期与共享内存
FrankenPHP 的每个 worker 是长期存活的 Go goroutine + PHP 执行环境,这意味着:
- 全局变量、static 属性、
apcu_add()存的数据,在 worker 重启前一直存在 —— 别假设每次请求都是干净状态 -
register_shutdown_function()在 worker 退出时才执行,不是每次请求结束;若依赖它做清理,可能漏掉 - 用
frankenphp.WorkerID()可区分不同 worker,适合做灰度更新时的分流标识 - 修改
.env或config/*.php后,不重启 worker 就无法生效 —— 没有热重载,这点比 Laravel Octane 还严格
真正要“发布更新”,最稳妥的方式仍是:生成新版本文件 → 发送 USR2 信号 → 等旧 worker 自然退出 → 新 worker 加载新代码。别指望纯 PHP 层绕过这个流程。



















