You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用PHP向iOS设备推送通知?服务器搭建方法咨询

PHP 搭建 iOS 推送通知服务器指南(针对已获取设备令牌场景)

嘿,既然你已经在Swift 4 + Xcode 10环境下用UserNotifications完成了设备注册,拿到了设备令牌,那搭建PHP推送服务器其实就差最后几步了,我一步步给你捋清楚:

一、先搞定APNs推送证书转换

苹果的APNs服务需要证书验证,你应该已经在开发者后台创建了推送证书(区分开发/生产环境),接下来要把导出的.p12文件转换成PHP能识别的.pem格式:

  • 打开终端,执行这条命令(替换成你的证书路径):
    openssl pkcs12 -in your_push_certificate.p12 -out apns_cert.pem -nodes -clcerts
    
  • 如果你的.p12设置了密码,执行时会提示输入,记得后续PHP代码里要对应配置。
  • 注意:开发环境用Sandbox证书,生产环境用Production证书,别搞混!

二、PHP推送代码实现(两种方式)

方式1:传统二进制协议(兼容旧环境)

这种方式用socket连接APNs服务器,适合没有HTTP/2支持的环境:

<?php
// 替换成你获取到的设备令牌(记得去掉空格)
$deviceToken = 'abc123456789abc123456789abc123456789abc123456789abc123456789abc1';

// 你的pem证书路径
$certificatePath = './apns_cert.pem';

// 推送内容,遵循APNs格式
$payload = json_encode([
    'aps' => [
        'alert' => [
            'title' => '来自PHP的测试推送',
            'body' => '这是一条测试通知!'
        ],
        'sound' => 'default',
        'badge' => 1
    ]
]);

// 选择环境:开发环境用sandbox,生产环境切换到下面的地址
$apnsServer = 'ssl://gateway.sandbox.push.apple.com:2195';
// $apnsServer = 'ssl://gateway.push.apple.com:2195'; // 生产环境

// 创建SSL上下文
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', $certificatePath);
// 如果证书有密码,解开下面这行并填写密码
// stream_context_set_option($ctx, 'ssl', 'passphrase', 'your_cert_password');

// 连接APNs服务器
$fp = stream_socket_client(
    $apnsServer, $err,
    $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx
);

if (!$fp) {
    exit("连接APNs失败: $err $errstr" . PHP_EOL);
}

echo '成功连接到APNs服务器' . PHP_EOL;

// 构建二进制推送消息
$msg = chr(0) . pack('n', 32) . pack('H*', str_replace(' ', '', $deviceToken)) . pack('n', strlen($payload)) . $payload;

// 发送推送
$result = fwrite($fp, $msg, strlen($msg));

if (!$result) {
    echo '推送发送失败' . PHP_EOL;
} else {
    echo '推送发送成功!' . PHP_EOL;
}

// 关闭连接
fclose($fp);
?>

方式2:HTTP/2协议(苹果推荐)

这种方式更现代,能返回详细的错误信息,需要你的PHP环境支持HTTP/2(需安装nghttp2扩展,curl版本>=7.47.0):

<?php
$deviceToken = 'abc123456789abc123456789abc123456789abc123456789abc123456789abc1';
$certPath = './apns_cert.pem';
$certPass = 'your_cert_password'; // 证书密码(如果有的话)
$bundleId = 'com.your.app.bundleid'; // 替换成你的App Bundle ID

// 推送内容
$payload = json_encode([
    'aps' => [
        'alert' => 'PHP HTTP/2测试推送',
        'sound' => 'default'
    ]
]);

// 环境URL:开发环境用development,生产环境用push
$url = "https://api.development.push.apple.com/3/device/$deviceToken";
// $url = "https://api.push.apple.com/3/device/$deviceToken"; // 生产环境

// 请求头
$headers = [
    "apns-topic: $bundleId",
    'Content-Type: application/json'
];

// 初始化curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSLCERT, $certPath);
curl_setopt($ch, CURLOPT_SSLCERTPASSWD, $certPass);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0); // 启用HTTP/2

// 执行请求
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

// 处理结果
if ($httpCode == 200) {
    echo '推送成功!';
} else {
    echo "推送失败,HTTP状态码: $httpCode,响应信息: $response";
}

curl_close($ch);
?>

三、测试必看注意事项

  • 设备令牌格式:确保你上传到服务器的令牌是十六进制字符串(Swift里可以用deviceToken.map { String(format: "%02.2hhx", $0) }.joined()转换),不要有空格或多余字符。
  • 环境匹配:开发环境用Sandbox证书+测试设备(安装开发包),生产环境用Production证书+上架/Ad Hoc包,混配会导致推送失败。
  • 端口开放:服务器要开放2195端口(二进制协议)或443端口(HTTP/2协议),避免防火墙拦截。
  • PHP环境检查:确保curl扩展已启用,HTTP/2方式需要额外安装nghttp2扩展。

四、Swift端小补充(确认配置)

你已经完成了UserNotifications注册,再检查下这两点:

  1. 已经请求了通知权限:
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
    // 请求通知权限
    UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
        if granted {
            DispatchQueue.main.async {
                application.registerForRemoteNotifications()
            }
        }
    }
    return true
}
  1. 正确获取设备令牌并上传:
func application(_ application: UIApplication, didRegisterForRemoteNotificationsWithDeviceToken deviceToken: Data) {
    let tokenString = deviceToken.map { String(format: "%02.2hhx", $0) }.joined()
    print("设备令牌:\(tokenString)")
    // 这里把tokenString上传到你的PHP服务器存储
}

内容的提问来源于stack exchange,提问作者Ryland Goldman

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:26:22