frankenphp未提供mercure_publish()函数,需用curl向/.well-known/mercure发送带hs256签名jwt的post请求,密钥、url、header(authorization、content-type)必须严格匹配caddyfile配置。

mercure_publish() 函数根本不存在
FrankenPHP 没有提供 mercure_publish() 这个函数,任何文档或代码里出现它,都是误传或混淆了 Symfony Mercure 组件的 API。FrankenPHP 的 Mercure 是 Go 层内置 Hub,PHP 侧不暴露原生函数接口——你得自己发 HTTP 请求。
必须用 curl 向 /.well-known/mercure POST
发布消息唯一可靠的方式是构造一个带 JWT 的 POST 请求,目标地址是 Mercure Hub 的 discovery endpoint:/.well-known/mercure。关键点不是“怎么调用”,而是“请求能不能被 Hub 接收并校验通过”:
- URL 必须指向 Hub 实际监听地址:Docker 内 PHP 进程不能用
http://localhost:8080/.well-known/mercure,Mac/Windows 用http://host.docker.internal:8080/.well-known/mercure,Linux 用http://172.17.0.1:8080/.well-known/mercure - JWT 必须由
MERCURE_PUBLISHER_JWT_KEY(或 Caddyfile 中publisher_jwt配置)签发,且 payload 至少含mercure.publish字段,值为字符串数组,如{"mercure":{"publish":["https://example.com/notifications"]}} - 签名算法只能是 HS256;密钥字符串必须字节级一致——如果 Caddyfile 里写的是
publisher_jwt mykey,PHP 里就绝不能用base64_encode('mykey')当密钥 - HTTP 头必须包含:
Authorization: Bearer <your_token></your_token>、Content-Type: application/json;Accept: text/event-stream可选但建议带上
curl_setopt 设置容易漏掉的关键项
用 curl_exec() 发布时,以下几项不显式设置,大概率失败或超时:
-
CURLOPT_RETURNTRANSFER => true:否则curl_exec()返回true而非响应体,无法判断 403/401 -
CURLOPT_TIMEOUT_MS => 200:FrankenPHP Worker 对长连接敏感,Guzzle 等封装库可能复用连接导致 hang 住;cURL 显式设短超时更稳 -
CURLOPT_HTTPHEADER必须完整传入数组,漏掉Authorization或拼错Bearer前缀会直接 401 - 不要设
CURLOPT_FOLLOWLOCATION:Mercure Hub 不做重定向,开启反而干扰错误判断
测试时 curl -v http://.../.well-known/mercure 返回 404 怎么办
这说明 Hub 根本没启用,不是 JWT 或网络问题:
- 检查 Caddyfile 是否取消注释了
mercure { ... }块,且publisher_jwt和subscriber_jwt都已配置(两者可相同,但不能为空) - 确认环境变量是否生效:Docker 启动时加
-e MERCURE_PUBLISHER_JWT_KEY=...,或 Caddyfile 中明确写死密钥 - FrankenPHP 镜像默认不启动 Mercure,没有配置就不会监听该路径——
curl -v得到 404 是最典型的“未启用”信号 - 若用自定义 Caddyfile,确保它被正确加载(比如挂载进容器的路径、权限、文件名是否匹配启动参数)
curl -v 看响应状态码和 body,再比对密钥和主题 URI 的字节一致性。php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











