首页 > php教程 > php手册 > 正文

PHP实现APNS推送

php中文网
发布: 2016-06-06 20:07:50
原创
3743人浏览过

参考http://code.google.com/p/apns-php/作为修改 上面的项目实现很完全,其中包括了队列。服务端实现等,但是功能过于复杂。简单的使用觉得不顺手! 用了几个小时,参考其过程,写了一个class文件,直接使用即可。简单且好理解 闲话少说,上代码 ?php/*** @

参考http://code.google.com/p/apns-php/作为修改
上面的项目实现很完全,其中包括了队列。服务端实现等,但是功能过于复杂。简单的使用觉得不顺手!

用了几个小时,参考其过程,写了一个class文件,直接使用即可。简单且好理解
闲话少说,上代码

<?php
/**
* @file apns.php
* @synopsis  apple APNS class
* @author Yee, <rlk002@gmail.com>
* @version 1.0
* @date 2012-09-17 11:27:59
*/
<span id="more-996"></span>
    class APNS
    &#123;
        const ENVIRONMENT_PRODUCTION = 0;
        const ENVIRONMENT_SANDBOX = 1;
        const DEVICE_BINARY_SIZE = 32;
        const CONNECT_RETRY_INTERVAL = 1000000;
        const SOCKET_SELECT_TIMEOUT = 1000000;
        const COMMAND_PUSH = 1;
        const STATUS_CODE_INTERNAL_ERROR = 999;
        const ERROR_RESPONSE_SIZE = 6;
        const ERROR_RESPONSE_COMMAND = 8;
        const PAYLOAD_MAXIMUM_SIZE = 256;
        const APPLE_RESERVED_NAMESPACE = 'aps';
        protected $_environment;
        protected $_providerCertificateFile;
        protected $_rootCertificationAuthorityFile;
        protected $_connectTimeout;
        protected $_connectRetryTimes = 3;
        protected $_connectRetryInterval;
        protected $_socketSelectTimeout;
        protected $_hSocket;
        protected $_deviceTokens = array&#40;&#41;;
        protected $_text;
        protected $_badge;
        protected $_sound;
        protected $_customProperties;
        protected $_expiryValue = 604800;
        protected $_customIdentifier;
        protected $_autoAdjustLongPayload = true;
        protected $asurls = array&#40;'ssl://gateway.push.apple.com:2195','ssl://gateway.sandbox.push.apple.com:2195'&#41;;
        protected $_errorResponseMessages = array
                            &#40;
                                0   => 'No errors encountered',
                                1 => 'Processing error',
                                2 => 'Missing device token',
                                3 => 'Missing topic',
                                4 => 'Missing payload',
                                5 => 'Invalid token size',
                                6 => 'Invalid topic size',
                                7 => 'Invalid payload size',
                                8 => 'Invalid token',
                                self::STATUS_CODE_INTERNAL_ERROR => 'Internal error'
                            &#41;;
        function __construct&#40;$environment,$providerCertificateFile&#41;
        &#123;
            if&#40;$environment != self::ENVIRONMENT_PRODUCTION && $environment != self::ENVIRONMENT_SANDBOX&#41; 
            &#123;
                throw new Exception&#40;
                    "Invalid environment '{$environment}'"
                &#41;;
            &#125;
            $this->_environment = $environment;
            if&#40;!is_readable&#40;$providerCertificateFile&#41;&#41; 
            &#123;
                throw new Exception&#40;
                    "Unable to read certificate file '{$providerCertificateFile}'"
                &#41;;
            &#125;
            $this->_providerCertificateFile = $providerCertificateFile;
            $this->_connectTimeout = @ini_get&#40;"default_socket_timeout"&#41;;
            $this->_connectRetryInterval = self::CONNECT_RETRY_INTERVAL;
            $this->_socketSelectTimeout = self::SOCKET_SELECT_TIMEOUT;
        &#125;
        public function setRCA&#40;$rootCertificationAuthorityFile&#41;
        &#123;
            if&#40;!is_readable&#40;$rootCertificationAuthorityFile&#41;&#41; 
            &#123;
                throw new Exception&#40;
                    "Unable to read Certificate Authority file '{$rootCertificationAuthorityFile}'"
                &#41;;
            &#125;
            $this->_rootCertificationAuthorityFile = $rootCertificationAuthorityFile;
        &#125;
        public function getRCA&#40;&#41;
        &#123;
            return $this->_rootCertificationAuthorityFile;
        &#125;
        protected function _connect&#40;&#41;
        &#123;
            $sURL = $this->asurls&#91;$this->_environment&#93;;
            $streamContext = stream_context_create&#40;
                array
                    &#40;
                        'ssl' => array
                        &#40;
                            'verify_peer' => isset&#40;$this->_rootCertificationAuthorityFile&#41;,
                            'cafile' => $this->_rootCertificationAuthorityFile,
                            'local_cert' => $this->_providerCertificateFile
                        &#41;
                    &#41;
                &#41;;
            $this->_hSocket = @stream_socket_client&#40;$sURL,$nError,$sError,$this->_connectTimeout,STREAM_CLIENT_CONNECT, $streamContext&#41;;
            if &#40;!$this->_hSocket&#41; 
            &#123;
                throw new Exception
                &#40;
                    "Unable to connect to '{$sURL}': {$sError} ({$nError})"
                &#41;;
            &#125;
            stream_set_blocking&#40;$this->_hSocket, 0&#41;;
            stream_set_write_buffer&#40;$this->_hSocket, 0&#41;;
            return true;
        &#125;
        public function connect&#40;&#41;
        &#123;
            $bConnected = false;
            $retry = 0;
            while&#40;!$bConnected&#41; 
            &#123;
                try 
                &#123;
                    $bConnected = $this->_connect&#40;&#41;;
                &#125;catch &#40;Exception $e&#41; 
                &#123;
                    if &#40;$nRetry >= $this->_connectRetryTimes&#41; 
                    &#123;
                        throw $e;
                    &#125;else 
                    &#123;
                        usleep&#40;$this->_nConnectRetryInterval&#41;;
                    &#125;
                &#125;
                $retry++;
            &#125;
        &#125;
        public function disconnect&#40;&#41;
        &#123;
            if &#40;is_resource&#40;$this->_hSocket&#41;&#41; 
            &#123;
                return fclose&#40;$this->_hSocket&#41;;
            &#125;
            return false;
        &#125;
        protected function getBinaryNotification&#40;$deviceToken, $payload, $messageID = 0, $Expire = 604800&#41;
        &#123;
            $tokenLength = strlen&#40;$deviceToken&#41;;
            $payloadLength = strlen&#40;$payload&#41;;
            $ret  = pack&#40;'CNNnH*', self::COMMAND_PUSH, $messageID, $Expire > 0 ? time&#40;&#41; + $Expire : 0, self::DEVICE_BINARY_SIZE, $deviceToken&#41;;
            $ret .= pack&#40;'n', $payloadLength&#41;;
            $ret .= $payload;
            return $ret;
        &#125;
        protected function readErrorMessage&#40;&#41;
        &#123;
            $errorResponse = @fread&#40;$this->_hSocket, self::ERROR_RESPONSE_SIZE&#41;;
            if &#40;$errorResponse === false || strlen&#40;$errorResponse&#41; != self::ERROR_RESPONSE_SIZE&#41; 
            &#123;
                return;
            &#125;
            $errorResponse = $this->parseErrorMessage&#40;$errorResponse&#41;;
            if &#40;!is_array&#40;$errorResponse&#41; || empty&#40;$errorResponse&#41;&#41; 
            &#123;
                return;
            &#125;
            if &#40;!isset&#40;$errorResponse&#91;'command'&#93;, $errorResponse&#91;'statusCode'&#93;, $errorResponse&#91;'identifier'&#93;&#41;&#41; 
            &#123;
                return;
            &#125;
            if &#40;$errorResponse&#91;'command'&#93; != self::ERROR_RESPONSE_COMMAND&#41; 
            &#123;
                return;
            &#125;
            $errorResponse&#91;'timeline'&#93; = time&#40;&#41;;
            $errorResponse&#91;'statusMessage'&#93; = 'None (unknown)';
            if &#40;isset&#40;$this->_aErrorResponseMessages&#91;$errorResponse&#91;'statusCode'&#93;&#93;&#41;&#41; 
            &#123;
                $errorResponse&#91;'statusMessage'&#93; = $this->_errorResponseMessages&#91;$errorResponse&#91;'statusCode'&#93;&#93;;
            &#125;
            return $errorResponse;
        &#125;
        protected function parseErrorMessage&#40;$errorMessage&#41;
        &#123;
            return unpack&#40;'Ccommand/CstatusCode/Nidentifier', $errorMessage&#41;;
        &#125;
        public function send&#40;&#41;
        &#123;
            if &#40;!$this->_hSocket&#41; 
            &#123;
                throw new Exception
                &#40;
                    'Not connected to Push Notification Service'
                &#41;;
            &#125;
            $sendCount = $this->getDTNumber&#40;&#41;;
            $messagePayload = $this->getPayload&#40;&#41;;
            foreach&#40;$this->_deviceTokens AS $key => $value&#41;
            &#123;
                $apnsMessage = $this->getBinaryNotification&#40;$value, $messagePayload, $messageID = 0, $Expire = 604800&#41;;
                $nLen = strlen&#40;$apnsMessage&#41;;
                $aErrorMessage = null;
                if &#40;$nLen !== &#40;$nWritten = &#40;int&#41;@fwrite&#40;$this->_hSocket, $apnsMessage&#41;&#41;&#41; 
                &#123;
                    $aErrorMessage = array
                    &#40;
                        'identifier' => $key,
                        'statusCode' => self::STATUS_CODE_INTERNAL_ERROR,
                        'statusMessage' => sprintf&#40;'%s (%d bytes written instead of %d bytes)',$this->_errorResponseMessages&#91;self::STATUS_CODE_INTERNAL_ERROR&#93;, $nWritten, $nLen&#41;
                    &#41;;
                &#125;
            &#125;
        &#125;
        public function addDT&#40;$deviceToken&#41;
        &#123;
            if &#40;!preg_match&#40;'~^[a-f0-9]{64}$~i', $deviceToken&#41;&#41; 
            &#123;
                throw new Exception
                &#40;
                    "Invalid device token '{$deviceToken}'"
                &#41;;
            &#125;
            $this->_deviceTokens&#91;&#93; = $deviceToken;
        &#125;       
        public function getDTNumber&#40;&#41;
        &#123;
            return count&#40;$this->_deviceTokens&#41;;
        &#125;
        public function setText&#40;$text&#41;
        &#123;
            $this->_text = $text;
        &#125;
        public function getText&#40;&#41;
        &#123;
            return $this->_text;
        &#125;
        public function setBadge&#40;$badge&#41;
        &#123;
            if &#40;!is_int&#40;$badge&#41;&#41; 
            &#123;
                throw new Exception
                &#40;
                    "Invalid badge number '{$badge}'"
                &#41;;
            &#125;
            $this->_badge = $badge;
        &#125;
        public function getBadge&#40;&#41;
        &#123;
            return $this->_badge;
        &#125;
        public function setSound&#40;$sound = 'default'&#41;
        &#123;
            $this->_sound = $sound;
        &#125;
        public function getSound&#40;&#41;
        &#123;
            return $this->_sound;
        &#125;
        public function setCP&#40;$name, $value&#41;
        &#123;
            if &#40;$name == self::APPLE_RESERVED_NAMESPACE&#41; 
            &#123;
                throw new Exception
                &#40;
                    "Property name '" . self::APPLE_RESERVED_NAMESPACE . "' can not be used for custom property."
                &#41;;
            &#125;
            $this->_customProperties&#91;trim&#40;$name&#41;&#93; = $value;
        &#125;
        protected function _getPayload&#40;&#41;
        &#123;
            $aPayload&#91;self::APPLE_RESERVED_NAMESPACE&#93; = array&#40;&#41;;
            if &#40;isset&#40;$this->_text&#41;&#41; 
            &#123;
                $aPayload&#91;self::APPLE_RESERVED_NAMESPACE&#93;&#91;'alert'&#93; = &#40;string&#41;$this->_text;
            &#125;
            if &#40;isset&#40;$this->_badge&#41; && $this->_badge > 0&#41; 
            &#123;
                $aPayload&#91;self::APPLE_RESERVED_NAMESPACE&#93;&#91;'badge'&#93; = &#40;int&#41;$this->_badge;
            &#125;
            if &#40;isset&#40;$this->_sound&#41;&#41; 
            &#123;
                $aPayload&#91;self::APPLE_RESERVED_NAMESPACE&#93;&#91;'sound'&#93; = &#40;string&#41;$this->_sound;
            &#125;
            if &#40;is_array&#40;$this->_customProperties&#41;&#41; 
            &#123;
                foreach&#40;$this->_customProperties as $propertyName => $propertyValue&#41; 
                &#123;
                    $aPayload&#91;$propertyName&#93; = $propertyValue;
                &#125;
            &#125;
            return $aPayload;
        &#125;
        public function setExpiry&#40;$expiryValue&#41;
        &#123;
            if &#40;!is_int&#40;$expiryValue&#41;&#41; 
            &#123;
                throw new Exception
                &#40;
                    "Invalid seconds number '{$expiryValue}'"
                &#41;;
            &#125;
            $this->_expiryValue = $expiryValue;
        &#125;
        public function getExpiry&#40;&#41;
        &#123;
            return $this->_expiryValue;
        &#125;
        public function setCustomIdentifier&#40;$customIdentifier&#41;
        &#123;
            $this->_customIdentifier = $customIdentifier;
        &#125;
        public function getCustomIdentifier&#40;&#41;
        &#123;
            return $this->_customIdentifier;
        &#125;       
        public function getPayload&#40;&#41;
        &#123;
            $sJSONPayload = str_replace
            &#40;
                '"' . self::APPLE_RESERVED_NAMESPACE . '":[]',
                '"' . self::APPLE_RESERVED_NAMESPACE . '":{}',
                json_encode&#40;$this->_getPayload&#40;&#41;&#41;
            &#41;;
            $nJSONPayloadLen = strlen&#40;$sJSONPayload&#41;;
            if &#40;$nJSONPayloadLen > self::PAYLOAD_MAXIMUM_SIZE&#41;
            &#123;
                if &#40;$this->_autoAdjustLongPayload&#41; 
                &#123;
                    $maxTextLen = $textLen = strlen&#40;$this->_text&#41; - &#40;$nJSONPayloadLen - self::PAYLOAD_MAXIMUM_SIZE&#41;;
                    if &#40;$nMaxTextLen > 0&#41;
                    &#123;
                        while &#40;strlen&#40;$this->_text = mb_substr&#40;$this->_text, 0, --$textLen, 'UTF-8'&#41;&#41; > $maxTextLen&#41;;
                        return $this->getPayload&#40;&#41;;
                    &#125;else
                    &#123;
                        throw new Exception
                        &#40;
                            "JSON Payload is too long: {$nJSONPayloadLen} bytes. Maximum size is " .
                            self::PAYLOAD_MAXIMUM_SIZE . " bytes. The message text can not be auto-adjusted."
                        &#41;;
                    &#125;
                &#125;else
                &#123;
                    throw new Exception
                    &#40;
                        "JSON Payload is too long: {$nJSONPayloadLen} bytes. Maximum size is " .
                        self::PAYLOAD_MAXIMUM_SIZE . " bytes"
                    &#41;;
                &#125;
            &#125;
            return $sJSONPayload;
        &#125;   
    &#125;
?>
登录后复制


使用办法:

    include 'apns.php';
    $rootpath = 'entrust_root_certification_authority.pem';  //ROOT证书地址
    $cp = 'production_push_certificates.pem';  //provider证书地址
    $apns = new APNS&#40;0,$cp&#41;;
    try
    &#123;
        $apns->setRCA&#40;$rootpath&#41;;  //设置ROOT证书
        $apns->connect&#40;&#41;; //连接
        $apns->addDT&#40;'b9d98721b5586b61a00fbfa0d61a033954e1bfb8faaae3dfc5a1382xxxxxx'&#41;;  //加入deviceToken
        $apns->setText&#40;'这是一条测试信息'&#41;;  //发送内容
        $apns->setBadge&#40;1&#41;;  //设置图标数
        $apns->setSound&#40;&#41;;  //设置声音
        $apns->setExpiry&#40;3600&#41;;  //过期时间
        $apns->setCP&#40;'fljt',array&#40;'type' => '1','url' => 'http://www.google.com.hk'&#41;&#41;;  //自定义操作
        $apns->send&#40;&#41;;  //发送
    &#125;catch&#40;Exception $e&#41;
    &#123;
        echo $e;
    &#125;
登录后复制

下载文件:apns

bee餐饮点餐外卖小程序
bee餐饮点餐外卖小程序

bee餐饮点餐外卖小程序是针对餐饮行业推出的一套完整的餐饮解决方案,实现了用户在线点餐下单、外卖、叫号排队、支付、配送等功能,完美的使餐饮行业更高效便捷!功能演示:1、桌号管理登录后台,左侧菜单 “桌号管理”,添加并管理你的桌号信息,添加以后在列表你将可以看到 ID 和 密钥,这两个数据用来生成桌子的二维码2、生成桌子二维码例如上面的ID为 308,密钥为 d3PiIY,那么现在去左侧菜单微信设置

bee餐饮点餐外卖小程序 1
查看详情 bee餐饮点餐外卖小程序
相关标签:
php
PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号