不能将极光和个推SDK同时加载进一个PHP进程,因为二者均采用静态单例模式重写HttpClient类,后加载的会覆盖前者全局实例,导致网络层错乱、返回401或空响应。

极光推送在 PHP 中能用,但直接集成个推(Getui)会遇到兼容性问题——两个 SDK 都依赖 curl 和自定义 HTTP 头,且个推的 PHP SDK(getui-push-api-php-sdk)已多年未维护,PHP 8+ 下常报 Deprecated: curl_setopt(): Passing null to parameter #3 ($value) of type string is deprecated 类错误。别硬凑一起用,该拆就拆。
为什么不能把极光和个推 SDK 同时加载进一个 PHP 进程
极光官方 SDK(jpush/jpush)和个推 SDK(getui-sdk-php)都重写了各自的 HttpClient 类,且都使用了静态单例模式。一旦先后 require,后加载的会覆盖前者的全局实例,导致后续调用 $client->push()->send() 实际走的是另一个 SDK 的网络层,返回 401 Unauthorized 或空响应。
- 极光 SDK 初始化时注册了
JPush\Client类,内部用curl_init()+curl_setopt_array()封装请求 - 个推 SDK 初始化时注册了
IGtPush类,内部也用curl_init(),但对CURLOPT_POSTFIELDS的处理逻辑不同(比如自动 JSON 编码、强制 UTF-8 header) - 两者都未声明命名空间隔离或 autoloader 冲突策略,Composer autoload 会按 PSR-4 规则混载,极易引发类名/方法行为错乱
PHP 中真正可行的双通道推送方案
不是“同时用两个 SDK”,而是“按通道分离调用环境”。核心是避免类名冲突和连接复用干扰:
- 用
exec()或proc_open()启动独立子进程执行个推脚本,主进程只跑极光 —— 子进程自带干净的 autoloader 和 curl 上下文 - 将个推封装为轻量 HTTP 接口(如
/api/push/getui),用file_get_contents()或curl调用,不加载其 SDK - 改用极光的多平台能力兜底:极光本身支持华为、小米、OPPO、vivo 等厂商通道(需在控制台开启并配置证书),无需个推;个推仅在极光无法触达的长尾机型上作为 fallback,这时应单独建个推专用服务,不与业务 PHP 共进程
curl_setopt() 在混合推送中的典型报错与绕过方式
常见现象:加载个推 SDK 后,极光 send() 返回空数组,curl_error() 显示 SSL read: errno=0;或个推 pushMessageToSingle() 报 Invalid request body,但极光正常。
立即学习“PHP免费学习笔记(深入)”;
- 根本原因是两个 SDK 对
CURLOPT_SSL_VERIFYPEER、CURLOPT_HTTPHEADER、CURLOPT_POSTFIELDS的默认值互不兼容,且没有 reset 机制 - 不要试图用
curl_reset()修复 —— 它只重置句柄,不清理已注册的全局配置 - 正确做法:每个推送动作必须使用全新
curl_init()句柄,并显式设置全部必要选项(包括CURLOPT_USERAGENT、CURLOPT_TIMEOUT、CURLOPT_HTTPHEADER) - 示例极光裸调(不依赖 SDK)关键段:
$ch = curl_init('https://api.jpush.cn/v3/push'); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($payload)); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Authorization: Basic ' . base64_encode($appKey . ':' . $masterSecret), 'Content-Type: application/json' ]); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $response = curl_exec($ch); curl_close($ch);
真正在生产环境跑双通道,别信“一个 Composer install 全搞定”的说法。极光和个推的底层通信契约不一致,强行共存只会让错误出现在最不好 debug 的地方 —— 比如某次批量推送中,5% 的设备收不到,而日志里只有 curl 超时,实际是 header 被个推 SDK 悄悄改写了。



















