Sample Apple Push Notification PHP Script
This is an old script that I used to use for sending notifications. I don’t remember the source, on the other hand, it has been modified a couple of times already.
Even though I could manage to send notifications with this script, the Apple server was rejecting the connection after the amount reaches more than 50. It was usually getting cut off around 70. So it needs to get some management for not sending in a loop, like threading or whatever.
<?php
// set time limit to zero in order to avoid timeout
set_time_limit(0);
// charset header for output
header('content-type: text/html; charset: utf-8');
// this is the pass phrase you defined when creating the key
$passphrase = 'my_secret_pass';
// you can post a variable to this string or edit the message here
if (!isset($_POST['msg'])) {
$_POST['msg'] = "Notification message here!";
}
// tr_to_utf function needed to fix the Turkish characters
$message = tr_to_utf($_POST['msg']);
// load your device ids to an array
$deviceIds = array(
'lh142lk3h1o2141p2y412d3yp1234y1p4y1d3j4u12p43131p4y1d3j4u12p4313',
'y1p4y1d3j4u12p43131p4y1d3j4u12p4313lh142lk3h1o2141p2y412d3yp1234'
);
// this is where you can customize your notification
$payload = '{"aps":{"alert":"' . $message . '","sound":"default"}}';
$result = 'Start' . '<br />';
////////////////////////////////////////////////////////////////////////////////
// start to create connection
$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'MyAppGenerated.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);
echo count($deviceIds) . ' devices will receive notifications.<br />';
foreach ($deviceIds as $item) {
// wait for some time
sleep(1);
// Open a connection to the APNS server
$fp = stream_socket_client('ssl://gateway.push.apple.com:2195', $err, $errstr, 60, STREAM_CLIENT_CONNECT | STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp) {
exit("Failed to connect: $err $errstr" . '<br />');
} else {
echo 'Apple service is online. ' . '<br />';
}
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $item) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
if (!$result) {
echo 'Undelivered message count: ' . $item . '<br />';
} else {
echo 'Delivered message count: ' . $item . '<br />';
}
if ($fp) {
fclose($fp);
echo 'The connection has been closed by the client' . '<br />';
}
}
echo count($deviceIds) . ' devices have received notifications.<br />';
// function for fixing Turkish characters
function tr_to_utf($text) {
$text = trim($text);
$search = array('Ü', 'Þ', 'Ð', 'Ç', 'Ý', 'Ö', 'ü', 'þ', 'ð', 'ç', 'ý', 'ö');
$replace = array('Ü', 'Åž', 'Ğž', 'Ç', 'İ', 'Ö', 'ü', 'ÅŸ', 'ÄŸ', 'ç', 'ı', 'ö');
$new_text = str_replace($search, $replace, $text);
return $new_text;
}
// set time limit back to a normal value
set_time_limit(30);Ed: AI-summarized comments from the original page (my old blog):
User comments that Apple rejects this method, perceiving rapid connection/disconnection as a denial-of-service attack, citing Apple’s documentation (2014) which advises to keep connections open:
https://developer.apple.com/library/ios/documentation/NetworkingInternet/Conceptual/RemoteNotificationsPG/Chapters/CommunicatingWIthAPS.html#//apple_ref/doc/uid/TP40008194-CH101-SW6Author (2014) thanks for the info, notes the code is old, and even then, Apple would automatically close the connection after 50-70 notifications. Suggests the method might not be possible now.
User reports that only 50 notifications are sent before stopping, asking how to send 10,000 pushes.
Author suggests storing tokens in a database and marking them as sent using a cron job to call the PHP script regularly. Also suggests using a service like Parse.
User reports hearing that Apple cuts the connection if you try to send to users who have refused notifications, linking to another post:
http://www.yasinturkoglu.com/ios-da-uzaktan-bildirimler-nam-i-diger-apns-apple-push-notification-service-remote-notifications/#comment-7001Author finds the claim interesting and notes that if true, their statistics would be strange. Suggests the best solution remains a scheduled task to send to unsent tokens until the connection breaks, then marking the records as sent.

