无需Node.js,PHP能否发送推送通知?已存储pushSubscription数据
仅用PHP发送Web推送通知的可行方案
完全可以仅通过PHP发送Web推送通知,不需要依赖Node.js——只要你已经存储了客户端的pushSubscription数据(包含endpoint、keys.p256dh和keys.auth),PHP就能完成HTTP请求发送和消息加密的核心逻辑。
具体实现步骤
1. 优先使用成熟PHP库(降低复杂度)
推荐使用minishlink/web-push库,它封装了Web推送的加密、请求构造等细节,适配不同浏览器的推送服务(如FCM、Mozilla推送服务)。
- 安装方式:通过Composer执行命令:
composer require minishlink/web-push - 若虚拟主机不支持Composer,可直接下载库的源码手动引入项目。
2. 配置VAPID密钥(可选但推荐)
VAPID是推送服务识别服务器身份的机制,能提升推送送达率,现代浏览器大多支持:
- 生成密钥对:用库自带命令生成:
vendor/bin/web-push generate-vapid-keys,得到公钥和私钥 - 公钥需要在前端注册推送时提供给客户端,私钥保存在服务器端用于签名请求
3. 编写推送代码示例
假设已从数据库取出订阅数据,结构如下:
$subscription = [ 'endpoint' => 'https://fcm.googleapis.com/fcm/send/xxx...', // 客户端推送端点 'keys' => [ 'p256dh' => 'xxx...', // 客户端公钥 'auth' => 'xxx...' // 客户端认证密钥 ] ];
使用minishlink/web-push发送推送的代码:
require __DIR__ . '/vendor/autoload.php'; use Minishlink\WebPush\WebPush; use Minishlink\WebPush\Subscription; // 初始化推送实例 $webPush = new WebPush([ 'VAPID' => [ 'subject' => 'mailto:your-email@example.com', // 推送服务联系邮箱 'publicKey' => '你的VAPID公钥', 'privateKey' => '你的VAPID私钥', ], ]); // 转换订阅数据为库要求的对象 $subscriptionObj = Subscription::create($subscription); // 发送推送消息 $result = $webPush->sendOneNotification( $subscriptionObj, '这是一条来自PHP的推送通知' ); // 处理推送结果 if ($result->isSuccess()) { echo "推送成功"; } else { echo "推送失败:" . $result->getReason(); // 若返回410状态码,说明订阅已过期,需从数据库删除该记录 }
4. 手动实现(不依赖第三方库)
若不想用库,需手动完成以下核心步骤:
- 生成临时密钥对,通过ECDH算法结合客户端的
p256dh公钥生成共享密钥 - 使用AES-GCM算法加密推送内容
- 构造HTTP请求头(包含
Authorization、Content-Encoding、Encryption等字段),发送POST请求到endpoint - 根据响应状态码处理结果(如410表示订阅失效)
手动实现需要熟悉Web推送的加密规范,过程繁琐,仅适合深度定制场景。
5. 注意事项
- 确保PHP开启OpenSSL扩展(大部分虚拟主机默认支持),加密逻辑依赖该扩展
- 不同浏览器的
endpoint来自不同厂商,但代码无需区分,库会自动适配 - 定期清理数据库中失效的订阅记录(如推送返回410状态码时)
内容的提问来源于stack exchange,提问作者Ka Ke
相关产品推荐
相关产品推荐

