Skip to content

Instantly share code, notes, and snippets.

@joashp
Last active June 3, 2024 15:38
Show Gist options
  • Save joashp/b2f6c7e24127f2798eb2 to your computer and use it in GitHub Desktop.
Save joashp/b2f6c7e24127f2798eb2 to your computer and use it in GitHub Desktop.
Simple PHP script to send Android Push Notification, iOS Push Notification and Windows Phone 8 Push Notification
<?php
// Server file
class PushNotifications {
// (Android)API access key from Google API's Console.
private static $API_ACCESS_KEY = 'AIzaSyDG3fYAj1uW7VB-wejaMJyJXiO5JagAsYI';
// (iOS) Private key's passphrase.
private static $passphrase = 'joashp';
// (Windows Phone 8) The name of our push channel.
private static $channelName = "joashp";
// Change the above three vriables as per your app.
public function __construct() {
exit('Init function is not allowed');
}
// Sends Push notification for Android users
public function android($data, $reg_id) {
$url = 'https://android.googleapis.com/gcm/send';
$message = array(
'title' => $data['mtitle'],
'message' => $data['mdesc'],
'subtitle' => '',
'tickerText' => '',
'msgcnt' => 1,
'vibrate' => 1
);
$headers = array(
'Authorization: key=' .self::$API_ACCESS_KEY,
'Content-Type: application/json'
);
$fields = array(
'registration_ids' => array($reg_id),
'data' => $message,
);
return $this->useCurl($url, $headers, json_encode($fields));
}
// Sends Push's toast notification for Windows Phone 8 users
public function WP($data, $uri) {
$delay = 2;
$msg = "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
"<wp:Notification xmlns:wp=\"WPNotification\">" .
"<wp:Toast>" .
"<wp:Text1>".htmlspecialchars($data['mtitle'])."</wp:Text1>" .
"<wp:Text2>".htmlspecialchars($data['mdesc'])."</wp:Text2>" .
"</wp:Toast>" .
"</wp:Notification>";
$sendedheaders = array(
'Content-Type: text/xml',
'Accept: application/*',
'X-WindowsPhone-Target: toast',
"X-NotificationClass: $delay"
);
$response = $this->useCurl($uri, $sendedheaders, $msg);
$result = array();
foreach(explode("\n", $response) as $line) {
$tab = explode(":", $line, 2);
if (count($tab) == 2)
$result[$tab[0]] = trim($tab[1]);
}
return $result;
}
// Sends Push notification for iOS users
public function iOS($data, $devicetoken) {
$deviceToken = $devicetoken;
$ctx = stream_context_create();
// ck.pem is your certificate file
stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', self::$passphrase);
// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);
if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);
// Create the payload body
$body['aps'] = array(
'alert' => array(
'title' => $data['mtitle'],
'body' => $data['mdesc'],
),
'sound' => 'default'
);
// Encode the payload as JSON
$payload = json_encode($body);
// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;
// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));
// Close the connection to the server
fclose($fp);
if (!$result)
return 'Message not delivered' . PHP_EOL;
else
return 'Message successfully delivered' . PHP_EOL;
}
// Curl
private function useCurl(&$model, $url, $headers, $fields = null) {
// Open connection
$ch = curl_init();
if ($url) {
// Set the url, number of POST vars, POST data
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
// Disabling SSL Certificate support temporarly
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
if ($fields) {
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
}
// Execute post
$result = curl_exec($ch);
if ($result === FALSE) {
die('Curl failed: ' . curl_error($ch));
}
// Close connection
curl_close($ch);
return $result;
}
}
}
?>
<?php
require_once('PushNotifications.php');
// Message payload
$msg_payload = array (
'mtitle' => 'Test push notification title',
'mdesc' => 'Test push notification body',
);
// For Android
$regId = 'APA91bHdOmMHiRo5jJRM1jvxmGqhComcpVFDqBcPfLVvaieHeFI9WVrwoDeVVD1nPZ82rV2DxcyVv-oMMl5CJPhVXnLrzKiacR99eQ_irrYogy7typHQDb5sg4NB8zn6rFpiBuikNuwDQzr-2abV6Gl_VWDZlJOf4w';
// For iOS
$deviceToken = 'FE66489F304DC75B8D6E8200DFF8A456E8DAEACEC428B427E9518741C92C6660';
// For WP8
$uri = 'http://s.notify.live.net/u/1/sin/HmQAAAD1XJMXfQ8SR0b580NcxIoD6G7hIYP9oHvjjpMC2etA7U_xy_xtSAh8tWx7Dul2AZlHqoYzsSQ8jQRQ-pQLAtKW/d2luZG93c3Bob25lZGVmYXVsdA/EKTs2gmt5BG_GB8lKdN_Rg/WuhpYBv02fAmB7tjUfF7DG9aUL4';
// Replace the above variable values
PushNotifications::android($msg_payload, $regId);
PushNotifications::WP8($msg_payload, $uri);
PushNotifications::iOS($msg_payload, $deviceToken);
?>
@tzin111
Copy link

tzin111 commented May 31, 2016

hi, i need a little help here:
(for my ios app i used the GCM and not the apn)

  1. what is the // (iOS) Private key's passphrase.
    private static $passphrase = 'joashp';
    and from where i can take it.
  2. when i run the code i get:
    Failed to connect: 110 Connection timed out

someone can help please ?

@oussaki
Copy link

oussaki commented Jun 16, 2016

@tzin111 the passphrase is the password that you puts when you created your certificate !

@hiebye
Copy link

hiebye commented Jun 30, 2016

Hi I need help
it give error
Failed to connect: 110 Connection timed out
Please help

I try your code but still error ....

And this is my code:

// Put your device token here (without spaces):
$deviceToken = 'cbbb1c0b13bc4aceef7472f2df4d1c7f608f052cdf650843b70740abc7a659eb';

// Put your private key's passphrase here:
$passphrase = 'admin';

// Put your alert message here:
$message = array('title' => "Stmark", 'body' => "New News have been added");
$base = 1;

if (!$message || !$base)
exit('Example Usage: $php newspush.php 'Breaking News!'' . "\n");

////////////////////////////////////////////////////////////////////////////////

$ctx = stream_context_create();
stream_context_set_option($ctx, 'ssl', 'local_cert', 'stmarkPush.pem');
stream_context_set_option($ctx, 'ssl', 'passphrase', $passphrase);

// Open a connection to the APNS server
$fp = stream_socket_client(
'ssl://gateway.sandbox.push.apple.com:2195', $err,
$errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

if (!$fp)
exit("Failed to connect: $err $errstr" . PHP_EOL);

echo 'Connected to APNS' . PHP_EOL;

// Create the payload body
$body['aps'] = array(
'alert' => $message,
'badge' => $base,
'sound' => 'spray.wav'
);

// Encode the payload as JSON
$payload = json_encode($body);

// Build the binary notification
$msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

// Send it to the server
$result = fwrite($fp, $msg, strlen($msg));

if (!$result)
echo 'Message not delivered' . PHP_EOL;
else
echo 'Message successfully delivered' . PHP_EOL;

// Close the connection to the server
fclose($fp);

@vitolipari
Copy link

vitolipari commented Jul 6, 2016

Hi, for use it, i need to register in Google console or in Google Firebase Cloud Messaging ???

@nikiben
Copy link

nikiben commented Jul 8, 2016

Per @trbsi suggestion.. it works removing $model. Also getting JSON PARSE ERROR (fixed by removing the json_encode in the useCurl function, It was getting encoded twice). Below works for Android and iOS. Not tested for Windows yet.

// Server file
class PushNotifications {
    // (Android)API access key from Google API Console.
    private static $API_ACCESS_KEY = "AIzaSyDG3fYAj1uW7VB-wejaMJyJXiO5JagAsYI";
    // (iOS) Private key passphrase.
    private static $passphrase = "joashp";
    // (Windows Phone 8) The name of our push channel.
    private static $channelName = "joashp";

    // Change the above three vriables as per your app.

    public function __construct() {
        exit('Init function is not allowed');
    }

        // Sends Push notification for Android users
    public function android($data, $reg_id) {
            $url = 'https://android.googleapis.com/gcm/send';
            $message = array(
                'title' => $data['mtitle'],
                'message' => $data['mdesc'],
                'subtitle' => '',
                'tickerText' => '',
                'msgcnt' => 1,
                'vibrate' => 1
            );


            $headers = array(
                'Authorization: key=' .self::$API_ACCESS_KEY,
                'Content-Type: application/json'
            );

            $fields = array(
                'registration_ids' => array($reg_id),
                'data' => $message
            );

            return self::useCurl($url, $headers, json_encode($fields));
        }

    // Sends Push's toast notification for Windows Phone 8 users
    public function WP($data, $uri) {
        $delay = 2;
        $msg =  "<?xml version=\"1.0\" encoding=\"utf-8\"?>" .
                "<wp:Notification xmlns:wp=\"WPNotification\">" .
                    "<wp:Toast>" .
                        "<wp:Text1>".htmlspecialchars($data['mtitle'])."</wp:Text1>" .
                        "<wp:Text2>".htmlspecialchars($data['mdesc'])."</wp:Text2>" .
                    "</wp:Toast>" .
                "</wp:Notification>";

        $sendedheaders =  array(
            'Content-Type: text/xml',
            'Accept: application/*',
            'X-WindowsPhone-Target: toast',
            "X-NotificationClass: $delay"
        );

        $response = self::useCurl($uri, $sendedheaders, $msg);

        $result = array();
        foreach(explode("\n", $response) as $line) {
            $tab = explode(":", $line, 2);
            if (count($tab) == 2)
                $result[$tab[0]] = trim($tab[1]);
        }

        return $result;
    }

        // Sends Push notification for iOS users
    public function iOS($data, $devicetoken) {

        $deviceToken = $devicetoken;

        $ctx = stream_context_create();
        // ck.pem is your certificate file
        stream_context_set_option($ctx, 'ssl', 'local_cert', 'ck.pem');
        stream_context_set_option($ctx, 'ssl', 'passphrase', self::$passphrase);

        // Open a connection to the APNS server
        $fp = stream_socket_client(
            'ssl://gateway.sandbox.push.apple.com:2195', $err,
            $errstr, 60, STREAM_CLIENT_CONNECT|STREAM_CLIENT_PERSISTENT, $ctx);

        if (!$fp)
            exit("Failed to connect: $err $errstr" . PHP_EOL);

        // Create the payload body
        $body['aps'] = array(
            'alert' => array(
                'title' => $data['mtitle'],
                'body' => $data['mdesc'],
             ),
            'sound' => 'default'
        );

        // Encode the payload as JSON
        $payload = json_encode($body);

        // Build the binary notification
        $msg = chr(0) . pack('n', 32) . pack('H*', $deviceToken) . pack('n', strlen($payload)) . $payload;

        // Send it to the server
        $result = fwrite($fp, $msg, strlen($msg));

        // Close the connection to the server
        fclose($fp);

        if (!$result)
            return 'Message not delivered' . PHP_EOL;
        else
            return 'Message successfully delivered' . PHP_EOL;

    }

    // Curl 
    private function useCurl($url, $headers, $fields) {
            // Open connection
            $ch = curl_init();
            if ($url) {
                // Set the url, number of POST vars, POST data
                curl_setopt($ch, CURLOPT_URL, $url);
                curl_setopt($ch, CURLOPT_POST, true);
                curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
                curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

                // Disabling SSL Certificate support temporarly
                curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
                if ($fields) {
                    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
                }

                // Execute post
                $result = curl_exec($ch);
                if ($result === FALSE) {
                    die('Curl failed: ' . curl_error($ch));
                }

                // Close connection
                curl_close($ch);

                return $result;
        }
    }

}
?>`

Copy link

ghost commented Jul 19, 2016

Has Any one try this code for Windows Phone Notification ? If any one has try then help me to send push notifications on windows Phone.

@macroguy
Copy link

macroguy commented Aug 2, 2016

Dears,
This code is normally use to send notification using Device Token, that's means on device, I wonder if I need send a notification to each device installed application what the code will be.

@mortezakarimi
Copy link

Can I use your code to creat yii2 extension?

@Ausjorg
Copy link

Ausjorg commented Aug 19, 2016

where do I go to get the android api access key? I know I have to go to google console but like @vitolipari asked do I need to register an api with google cloud messaging in order to get an api key or is it somewhere else?

@rockji
Copy link

rockji commented Sep 1, 2016

this problem is not solved

@rockji
Copy link

rockji commented Sep 1, 2016

I use this code for ios push notification using php

@Revucurly
Copy link

am getting the following error,

Warning: curl_setopt(): You must pass either an object or an array with the CURLOPT_HTTPHEADER argument in G:\xampp\htdocs\push_notification\PushNotifications.php on line 115

Fatal error: Call to undefined method PushNotifications::WP8() in G:\xampp\htdocs\push_notification\TestNotifications.php on line 21

pls help.

@ILABUTK
Copy link

ILABUTK commented Nov 14, 2016

@Revucurly for the WP8(), it should be WP() as it was defined in the PushNotification class.

@djbinho
Copy link

djbinho commented Nov 28, 2016

Hi There,
I am having the same problem as irfanmiamik.
In iOS it is works fine, but in Android, it is showing only title as Toast :(
The body message ('message') doesn't appears.
How can I fix this ?
Thanks guys

@jchauhan16
Copy link

Hi,
I am using the above code to send push notifications on IOS in php. But at the application end, i am receiving incorrect json.
Please see the attached screen-shot.
pushios

Please suggest how to fix this.
Thanks in advance !!

@joel-extremo
Copy link

hi, where can i get the (Android)API access key from Google API's Console and the '$regId' for android??

@anikn
Copy link

anikn commented Mar 13, 2017

I used the code for android. But I am not getting any notification :(. Any idea how to solve ?

@laiqahmed440
Copy link

Hi there,
I have the php code for sending push notifications to ios device but I came up with the following errors;

Warning: failed loading cafile stream: C:/xampp/ca-bundle.crt' in C:\xampp\htdocs\las_files\PushNotifications.php on line 81

Warning: stream_socket_client(): Failed to enable crypto in C:\xampp\htdocs\las_files\PushNotifications.php on line 81

Warning: stream_socket_client(): unable to connect to ssl://gateway.sandbox.push.apple.com:2195 (Unknown error) in C:\xampp\htdocs\las_files\PushNotifications.php on line 81
Failed to connect: 0`

Can anyone of you help me in resolving it? I will be very thankful.

@ProdigyTech
Copy link

ProdigyTech commented Apr 2, 2017

Here's my solution for the android implementation to send a notification to a specific device

$API_ACCESS_KEY: go to the firebase console, navigate to the project, click the gear icon, project settings. Click on the tab "CLOUD MESSAGING"
should look like this:
image copy the server key from FCM and store it in $API_ACCESS_KEY

PushNotifications.php

class PushNotifications{
    private  static  $API_ACCESS_KEY = "YOUR_FCM_SERVER_KEY ";
    public function __construct() {
       // exit('Init function is not allowed');
   }
public function android($data, $reg_id) {
     $url = 'https://fcm.googleapis.com/fcm/send';
     $message = array
     (
         'title' => $data['mtitle'],
         'body' => $data['mdesc'],
         'subtitle' => '',
         'tickerText' => '',
         'msgcnt' => 1,
         'vibrate' => 1
     );

     $headers = array(
         'Content-Type:application/json',
         'Authorization:key='.self::$API_ACCESS_KEY
     );
     $fields = array(
         'notification' => $message,
         'to' => $reg_id,
     );
     return self::useCurl($url, $headers, $fields);
 }

private function useCurl($url, $headers , $fields) {
        $ch = curl_init();
        if ($url) {
            // Set the url, number of POST vars, POST data
            curl_setopt($ch, CURLOPT_URL, $url);
            curl_setopt($ch, CURLOPT_POST, true);
            curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
            curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

            // Disabling SSL Certificate support temporarly
            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
            if ($fields) {
                curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($fields));
            }
            // Execute post
            $result = curl_exec($ch);
            $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
            if ($result === FALSE) {
                die('Curl failed: ' . curl_error($ch));
            }
            // Close connection
            curl_close($ch);
       //checking the response code we get from fcm for debugging purposes
            echo "http response " . $httpcode;
       //checking the status/result of the push notif for debugging purposes
            echo $result;
            return $result;
        }

    }
}

`

Test Notifications.php

The SendToDevice Function is called once the server receives the POST request with the required parameters i.e After user submits the form
The function takes in a title, message, and a regID


function SendToDevice($title, $message, $regId)
{
    require_once('TestNotifications.php');
    // Message payload, using data from post request
    $msg_payload = array(
        'mtitle' => $title,
        'mdesc' => $message,
    );
    $var = new PushNotifications();
    $var->android($msg_payload, $regId);
}
if ( $_SERVER['REQUEST_METHOD'] == 'POST' && (!empty($_POST['SendTo']))) {
    SendToDevice($_POST['title'], $_POST['messageBody'], $_POST['SendTo']);
}

<!-- HTML Form that contains input fields to send notification data in POST request on submit -->
<!DOCTYPE HTML>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<h1>Test FCM from server to client! </h1>
</header>

<form method="POST" action = "TestNotifications.php">
    Who do you want to send the alert to?
    <select id = "SendTo" name="SendTo">
<!-- Put the FCM registration token in option value  --> 
        <option value="FCM registration token">Device 1</option>
    </select>
    <br />
    Title: <input tye="text" name ="title" id="title">
    <br />
    Message Body : <input type = "text", name = "messageBody">
    <br />
    <input type="submit" name="submit" id="submit">
</form>
</body>
</html>

@ccesarc
Copy link

ccesarc commented Aug 24, 2017

Good afternoon people,

I would like to know where I get this information:

// (iOS) Private key's passphrase.
private static $passphrase = 'joashp';

Thank you very much.

@wustenveld
Copy link

@ccesarc When you create your certificate file your asked to input a passphrase

@Curious-Confused-Dev
Copy link

Create this in OOPS approach! Create different classes for each function i.e. Follow Single Responsibility Principle

@xtrasmal
Copy link

xtrasmal commented Mar 1, 2018

This code still working in 2018?

@FoxyFire23
Copy link

Can anyone confirm if this is still operational

@Arturi001
Copy link

@OwaisArain
Copy link

Do we need to register our app in firebase to work with push notifications?

@debasislnsel
Copy link

I have used this code for get push notification in iOS. But getting some error. Please any one can help me.
Error:
Message: stream_socket_client(): SSL operation failed with code 1. OpenSSL Error messages:
error:14094410:SSL routines:ssl3_read_bytes:sslv3 alert handshake failure

@joashp
Copy link
Author

joashp commented Aug 22, 2019 via email

@jmarcher
Copy link

What? Are you always this arrogant? @cristo1985

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment