直接 composer require 失败因 lyralex/php-pushok 已归档,应改用活跃 fork edamov/pushok;初始化需严格满足 p8 密钥三要素(keyid、teamid、bundleid)且 path 传文件内容而非路径,开发环境须用 api.development.push.apple.com 地址。

为什么直接 composer require 会失败
因为 php-pushok 官方包(lyralex/php-pushok)已归档,不再维护,且其依赖的 ext-curl 和 TLS 1.2+ 要求容易在旧环境触发错误。更关键的是:它默认使用 APNs 的 https://api.push.apple.com 生产地址,但证书或密钥配置稍有偏差就会返回 403 Forbidden 或 401 Unauthorized —— 这不是 Composer 装不上的问题,而是后续调用时才暴露的权限校验失败。
- 别急着删 vendor 目录重装,先确认 PHP 版本 ≥7.4、
ext-openssl和ext-json已启用 - 运行
composer require minishlink/web-push不能替代php-pushok,前者走 Web Push 协议,不支持 APNs 原生推送 - 真正要装的是社区维护分支:
composer require edamov/pushok(当前最活跃 fork,支持 Token Auth 和 P8 密钥)
用 P8 密钥方式初始化 Client 的三个硬性条件
APNs 现在强制推荐使用 Token Authentication(P8 文件),而非证书。但初始化 Pushok\Client 时漏掉任意一项都会导致 Uncaught Exception: Invalid auth provider。
-
keyId必须是 Apple Developer Portal 中创建的密钥 ID(8位字母数字,如ABC12345XY),不是密钥文件名 -
teamId是你的 Apple 开发者账号 Team ID(10位字母数字,在 Membership 页面 查看) -
bundleId必须与 App 在 Xcode 中配置的 Bundle Identifier 完全一致(区分大小写),例如com.example.MyApp - P8 文件内容需用
file_get_contents()读取并传入,不能直接填路径字符串
$authProvider = new Pushok\AuthProvider\Token([
'keyId' => 'ABC12345XY',
'teamId' => 'DEF67890GH',
'bundleId' => 'com.example.MyApp',
'path' => file_get_contents('/path/to/AuthKey_ABC12345XY.p8'),
]);
$client = new Pushok\Client($authProvider, 'https://api.development.push.apple.com'); // 开发环境用 development 地址
send() 调用后返回空数组或 410 Gone 怎么办
空响应通常意味着请求被静默丢弃,410 Gone 则明确表示设备 token 已失效(用户卸载 App 或重装系统后未重新注册)。这不是网络超时,而是 APNs 的主动拒绝。
- 检查
$deviceToken是否为 64 字符十六进制字符串(不含空格、、<code>>、换行),常见错误是从 Xcode 控制台复制时带了多余符号 - 确认 App 已开启 Background Modes → Remote Notifications,并在
AppDelegate中调用application.registerForRemoteNotifications() - 开发环境下必须用
https://api.development.push.apple.com,生产环境用https://api.push.apple.com—— 混用会导致400 BadDeviceToken - 发送前加日志:
var_dump($client->getLastError());,比盲目重试更有效
批量推送时内存暴涨或超时的绕过方法
Pushok\Client::send() 默认串行发送,100 个 token 就发起 100 次 HTTPS 请求,PHP 进程容易卡死。官方没提供异步接口,得自己拆解。
- 不要用
foreach包裹send(),改用Pushok\Notification构建单个通知对象,再调用$client->push($notification, [$token1, $token2])批量提交(最多 500 个 token / 请求) - PHP CLI 环境下务必设置
set_time_limit(0),否则默认 30 秒超时会中断 - 若需更高吞吐,把 token 分组(每组 100 个),用
pcntl_fork()或 Supervisor 启多个进程,避免单进程阻塞 - 注意 APNs 对同一设备重复推送有限频(约每秒 1 次),高频触发可能被限流
Token 失效和环境地址错配是最常卡住的地方,其他问题基本能从 $client->getLastError() 里直接看到原因。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











