参考http://code.google.com/p/apns-php/作为修改 上面的项目实现很完全,其中包括了队列。服务端实现等,但是功能过于复杂。简单的使用觉得不顺手! 用了几个小时,参考其过程,写了一个class文件,直接使用即可。简单且好理解 闲话少说,上代码 ?php/*** @
参考http://code.google.com/p/apns-php/作为修改
上面的项目实现很完全,其中包括了队列。服务端实现等,但是功能过于复杂。简单的使用觉得不顺手!
用了几个小时,参考其过程,写了一个class文件,直接使用即可。简单且好理解
闲话少说,上代码
'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' ); function __construct($environment,$providercertificatefile) { if($environment != self::environment_production && $environment != self::environment_sandbox) { throw new exception( invalid environment '{$environment}' ); } $this->_environment = $environment; if(!is_readable($providercertificatefile)) { throw new exception( unable to read certificate file '{$providercertificatefile}' ); } $this->_providercertificatefile = $providercertificatefile; $this->_connecttimeout = @ini_get(default_socket_timeout); $this->_connectretryinterval = self::connect_retry_interval; $this->_socketselecttimeout = self::socket_select_timeout; } public function setrca($rootcertificationauthorityfile) { if(!is_readable($rootcertificationauthorityfile)) { throw new exception( unable to read certificate authority file '{$rootcertificationauthorityfile}' ); } $this->_rootcertificationauthorityfile = $rootcertificationauthorityfile; } public function getrca() { return $this->_rootcertificationauthorityfile; } protected function _connect() { $surl = $this->asurls[$this->_environment]; $streamcontext = stream_context_create( array ( 'ssl' => array ( 'verify_peer' => isset($this->_rootcertificationauthorityfile), 'cafile' => $this->_rootcertificationauthorityfile, 'local_cert' => $this->_providercertificatefile ) ) ); $this->_hsocket = @stream_socket_client($surl,$nerror,$serror,$this->_connecttimeout,stream_client_connect, $streamcontext); if (!$this->_hsocket) { throw new exception ( unable to connect to '{$surl}': {$serror} ({$nerror}) ); } stream_set_blocking($this->_hsocket, 0); stream_set_write_buffer($this->_hsocket, 0); return true; } public function connect() { $bconnected = false; $retry = 0; while(!$bconnected) { try { $bconnected = $this->_connect(); }catch (exception $e) { if ($nretry >= $this->_connectretrytimes) { throw $e; }else { usleep($this->_nconnectretryinterval); } } $retry++; } } public function disconnect() { if (is_resource($this->_hsocket)) { return fclose($this->_hsocket); } return false; } protected function getbinarynotification($devicetoken, $payload, $messageid = 0, $expire = 604800) { $tokenlength = strlen($devicetoken); $payloadlength = strlen($payload); $ret = pack('cnnnh*', self::command_push, $messageid, $expire > 0 ? time() + $expire : 0, self::device_binary_size, $devicetoken); $ret .= pack('n', $payloadlength); $ret .= $payload; return $ret; } protected function readerrormessage() { $errorresponse = @fread($this->_hsocket, self::error_response_size); if ($errorresponse === false || strlen($errorresponse) != self::error_response_size) { return; } $errorresponse = $this->parseerrormessage($errorresponse); if (!is_array($errorresponse) || empty($errorresponse)) { return; } if (!isset($errorresponse['command'], $errorresponse['statuscode'], $errorresponse['identifier'])) { return; } if ($errorresponse['command'] != self::error_response_command) { return; } $errorresponse['timeline'] = time(); $errorresponse['statusmessage'] = 'none (unknown)'; if (isset($this->_aerrorresponsemessages[$errorresponse['statuscode']])) { $errorresponse['statusmessage'] = $this->_errorresponsemessages[$errorresponse['statuscode']]; } return $errorresponse; } protected function parseerrormessage($errormessage) { return unpack('ccommand/cstatuscode/nidentifier', $errormessage); } public function send() { if (!$this->_hsocket) { throw new exception ( 'not connected to push notification service' ); } $sendcount = $this->getdtnumber(); $messagepayload = $this->getpayload(); foreach($this->_devicetokens as $key => $value) { $apnsmessage = $this->getbinarynotification($value, $messagepayload, $messageid = 0, $expire = 604800); $nlen = strlen($apnsmessage); $aerrormessage = null; if ($nlen !== ($nwritten = (int)@fwrite($this->_hsocket, $apnsmessage))) { $aerrormessage = array ( 'identifier' => $key, 'statuscode' => self::status_code_internal_error, 'statusmessage' => sprintf('%s (%d bytes written instead of %d bytes)',$this->_errorresponsemessages[self::status_code_internal_error], $nwritten, $nlen) ); } } } public function adddt($devicetoken) { if (!preg_match('~^[a-f0-9]{64}$~i', $devicetoken)) { throw new exception ( invalid device token '{$devicetoken}' ); } $this->_devicetokens[] = $devicetoken; } public function getdtnumber() { return count($this->_devicetokens); } public function settext($text) { $this->_text = $text; } public function gettext() { return $this->_text; } public function setbadge($badge) { if (!is_int($badge)) { throw new exception ( invalid badge number '{$badge}' ); } $this->_badge = $badge; } public function getbadge() { return $this->_badge; } public function setsound($sound = 'default') { $this->_sound = $sound; } public function getsound() { return $this->_sound; } public function setcp($name, $value) { if ($name == self::apple_reserved_namespace) { throw new exception ( property name ' . self::apple_reserved_namespace . ' can not be used for custom property. ); } $this->_customproperties[trim($name)] = $value; } protected function _getpayload() { $apayload[self::apple_reserved_namespace] = array(); if (isset($this->_text)) { $apayload[self::apple_reserved_namespace]['alert'] = (string)$this->_text; } if (isset($this->_badge) && $this->_badge > 0) { $apayload[self::apple_reserved_namespace]['badge'] = (int)$this->_badge; } if (isset($this->_sound)) { $apayload[self::apple_reserved_namespace]['sound'] = (string)$this->_sound; } if (is_array($this->_customproperties)) { foreach($this->_customproperties as $propertyname => $propertyvalue) { $apayload[$propertyname] = $propertyvalue; } } return $apayload; } public function setexpiry($expiryvalue) { if (!is_int($expiryvalue)) { throw new exception ( invalid seconds number '{$expiryvalue}' ); } $this->_expiryvalue = $expiryvalue; } public function getexpiry() { return $this->_expiryvalue; } public function setcustomidentifier($customidentifier) { $this->_customidentifier = $customidentifier; } public function getcustomidentifier() { return $this->_customidentifier; } public function getpayload() { $sjsonpayload = str_replace ( '' . self::apple_reserved_namespace . ':[]', '' . self::apple_reserved_namespace . ':{}', json_encode($this->_getpayload()) ); $njsonpayloadlen = strlen($sjsonpayload); if ($njsonpayloadlen > self::payload_maximum_size) { if ($this->_autoadjustlongpayload) { $maxtextlen = $textlen = strlen($this->_text) - ($njsonpayloadlen - self::payload_maximum_size); if ($nmaxtextlen > 0) { while (strlen($this->_text = mb_substr($this->_text, 0, --$textlen, 'utf-8')) > $maxtextlen); return $this->getpayload(); }else { throw new exception ( json payload is too long: {$njsonpayloadlen} bytes. maximum size is . self::payload_maximum_size . bytes. the message text can not be auto-adjusted. ); } }else { throw new exception ( json payload is too long: {$njsonpayloadlen} bytes. maximum size is . self::payload_maximum_size . bytes ); } } return $sjsonpayload; } }?>
使用办法:
include 'apns.php'; $rootpath = 'entrust_root_certification_authority.pem'; //root证书地址 $cp = 'production_push_certificates.pem'; //provider证书地址 $apns = new apns(0,$cp); try { $apns->setrca($rootpath); //设置root证书 $apns->connect(); //连接 $apns->adddt('b9d98721b5586b61a00fbfa0d61a033954e1bfb8faaae3dfc5a1382xxxxxx'); //加入devicetoken $apns->settext('这是一条测试信息'); //发送内容 $apns->setbadge(1); //设置图标数 $apns->setsound(); //设置声音 $apns->setexpiry(3600); //过期时间 $apns->setcp('fljt',array('type' => '1','url' => 'http://www.google.com.hk')); //自定义操作 $apns->send(); //发送 }catch(exception $e) { echo $e; }
下载文件:apns
原文地址:php实现apns推送, 感谢原作者分享。