使用.p8文件在php中发送iOS推送通知

Apple has updated their push notification service and the certificate file received is now a .p8 file. There are many examples online of how to send a push notification with the .pem file but I can't find anything for a .p8 file. Does anyone have any code that works with the .p8 file?

I have been trying to send push notification with new JWT based push notification service using PHP. Its was definitely not a easy task.

I have uploaded project on GitHub. You can download from there and make sure you replace your .p8 file with existing .p8 file.

Then in push.php file you need to replace your kid, iss(Team ID), token and app_bundle_id.

Go to the directory and from terminal run the command php push.php. If everything goes well then you should receive push notification.

This solution works well for me. Just make sure that you don't get any errors in terminal.

I hope this helps.

With the script below I'm able to send token-based push notifications with the .p8 file.

The minimum version of curl supporting this is 7.38.0, and it must be compiled with the flag --with-nghttp2 and openssl >= 1.0.2

<?php

  $keyfile = 'AuthKey_AABBCC1234.p8';               # <- Your AuthKey file
  $keyid = 'AABBCC1234';                            # <- Your Key ID
  $teamid = 'AB12CD34EF';                           # <- Your Team ID (see Developer Portal)
  $bundleid = 'com.company.YourApp';                # <- Your Bundle ID
  $url = 'https://api.development.push.apple.com';  # <- development url, or use http://api.push.apple.com for production environment
  $token = 'e2c48ed32ef9b018........';              # <- Device Token

  $message = '{"aps":{"alert":"Hi there!","sound":"default"}}';

  $key = openssl_pkey_get_private('file://'.$keyfile);

  $header = ['alg'=>'ES256','kid'=>$keyid];
  $claims = ['iss'=>$teamid,'iat'=>time()];

  $header_encoded = base64($header);
  $claims_encoded = base64($claims);

  $signature = '';
  openssl_sign($header_encoded . '.' . $claims_encoded, $signature, $key, 'sha256');
  $jwt = $header_encoded . '.' . $claims_encoded . '.' . base64_encode($signature);

  // only needed for PHP prior to 5.5.24
  if (!defined('CURL_HTTP_VERSION_2_0')) {
      define('CURL_HTTP_VERSION_2_0', 3);
  }

  $http2ch = curl_init();
  curl_setopt_array($http2ch, array(
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_2_0,
    CURLOPT_URL => "$url/3/device/$token",
    CURLOPT_PORT => 443,
    CURLOPT_HTTPHEADER => array(
      "apns-topic: {$bundleid}",
      "authorization: bearer $jwt"
    ),
    CURLOPT_POST => TRUE,
    CURLOPT_POSTFIELDS => $message,
    CURLOPT_RETURNTRANSFER => TRUE,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HEADER => 1
  ));

  $result = curl_exec($http2ch);
  if ($result === FALSE) {
    throw new Exception("Curl failed: ".curl_error($http2ch));
  }

  $status = curl_getinfo($http2ch, CURLINFO_HTTP_CODE);
  echo $status;

  function base64($data) {
    return rtrim(strtr(base64_encode(json_encode($data)), '+/', '-_'), '=');
  }

?>