PHP library for sending notifications via Apple Push Notification service (APNS) over HTTP/2.
composer require gepo/apns-http2
Since 29 March 2021, the AAA certificate is required. You can read about it and get it here: https://developer.apple.com/news/?id=7gx0a2lp.
On Ubuntu, you must put it in /usr/local/share/ca-certificates/extra/
(create the path if it doesn't exist), and run update-ca-certificates
as root
).
You need cURL with HTTP/2 support installed on your system for this library to work. cURL supports HTTP/2 starting version 7.43.0.
Here's a simple script to check if your installation supports cURL with HTTP/2:
<?php
defined('CURL_VERSION_HTTP2') || define('CURL_VERSION_HTTP2', 65536);
$version = curl_version();
if (($version['features'] & CURL_VERSION_HTTP2) !== 0) {
echo 'HTTP/2 supported'.PHP_EOL;
} else {
echo 'HTTP/2 not supported'.PHP_EOL;
}
Alternatively, you may check the cURL version in command line to make sure it's greater or equal to 7.43.0:
curl --version
#!/bin/bash
# Update version to latest, found here: https://curl.se/download/
VERSION=7.76.1
cd ~
sudo apt-get update -y
sudo apt-get install -y build-essential nghttp2 libnghttp2-dev libssl-dev wget
wget https://curl.haxx.se/download/curl-${VERSION}.tar.gz
tar -xzvf curl-${VERSION}.tar.gz && rm -f curl-${VERSION}.tar.gz && cd curl-${VERSION}
./configure --prefix=/usr/local --with-ssl --with-nghttp2
make -j4
sudo make install
sudo ldconfig
cd ~ && rm -rf curl-${VERSION}
This script is based on https://gist.github.com/jjpeleato/3327c2e38fc0fea7d6602401f9849809
To install it on OS X with Homebrew (the example is for PHP 5.6):
brew install curl --with-nghttp2 --with-openssl
brew link curl --force
brew reinstall php56 --with-homebrew-curl
<?php
require_once __DIR__ . '/vendor/autoload.php';
$client = new \Apns\Client(__DIR__ . '/certs/apns-dev-cert.pem', true); // true is for sandbox
$message = (new \Apns\Message())
->setDeviceIdentifier('a00915e74d60d71ba3fb80252a5e197b60f2e7743f61b4411c713e9aabd2854f')
->setAlert('Test message')
->setTopic('com.mycompany.myapp')
;
$client->send($message);
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Apns\Client as ApnsClient;
use Apns\Message as ApnsMessage;
use Apns\Exception\ApnsException;
$token = 'a00915e74d60d71ba3fb80252a5e197b60f2e7743f61b4411c713e9aabd2854f';
// Check if token format is valid
if ((!ctype_xdigit($token)) || (64 != strlen($token))) {
die('Token is invalid!');
}
// Create client with production certificate and passphrase
$client = new ApnsClient(
[
__DIR__ . '/certs/apns-prod-cert.pem',
'my-passphrase'
],
false // false is for production
);
// Get topic from certificate file
if ($cert = openssl_x509_parse(file_get_contents($apnsClient->getSslCert()[0]))) {
$topic = $cert['subject']['UID'];
}
// Create message
$message = (new ApnsMessage())
->setDeviceIdentifier($token)
->setAlert('This is a test message sent on '.gmdate('r'))
->setData([
'Key1' => 'Value1',
'Key2' => 'Value2',
'Key3' => 'Value3',
])
->setTopic($topic);
// Send it and catch errors
try {
$client->send($message);
} catch (ApnsException $e) {
// https://developer.apple.com/library/archive/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/CommunicatingwithAPNs.html#//apple_ref/doc/uid/TP40008194-CH11-SW17
switch ($e->getMessage()) {
case 'BadDeviceToken':
case 'ExpiredProviderToken':
case 'InvalidProviderToken':
case 'MissingProviderToken':
case 'Unregistered':
// do something, ie. remove the token from your list
break;
case 'BadCollapseId':
case 'BadExpirationDate':
case 'BadMessageId':
case 'BadPriority':
// do something, ie. check your parameters
break;
case 'BadTopic':
case 'MissingTopic':
case 'DeviceTokenNotForTopic':
// do something, ie. check that your topic is ok
break;
case 'BadCertificate':
// do something, ie. check the certificate you provided
break;
case 'BadCertificateEnvironment':
// do something, ie. check your certificate/environment (sandbox or production)
break;
case 'TooManyRequests':
case 'TooManyProviderTokenUpdates':
// do something, ie. throttle your requests
break;
default:
// do something
break;
}
}