最新消息:博客断断续续关停过,感谢保留友链的友们,以后本博客可能会比较少更新,但是会一直开下去,并保持稳定性。

极光推送 V3 服务器端 php 版使用实例

技术交流 东子 2701次浏览 抢沙发 无图浏览

公司项目需要WEB端给APP(安卓和IOS客户端)推送消息,一般的WEB端API接口是实现不了的,要用到“云”推送。看了下网友评论极光和百度云都不错,不过还是研究了下极光。

从官网下载了极光v3 php版的代码包,又看了看文档,不知道是我智商低还是极光的文档确实差劲,用官方的代码一直报错,文档也没有实用点的搭建说明,我承认我很菜。网上有几篇关于服务器端php的教程,于是和一个博主交流了下,感谢 dodobook.net 博主的指导,我比较顺利的解决了问题。

有两篇文章推荐参考:

  1. 【DoDoBook博客】http://www.dodobook.net/php/780
  2. 【bubuko博客】http://www.bubuko.com/infodetail-589128.html

后来和DoDoBook博主交流,他用的不是ThinkPHP,我之前以为他是TP,于是我稍微改了下,封装成类,在其他php项目也是通用的,只不过没封装类的情况下,需要引用Jpush文件,然后再实例化。名字随意自定义,但要注意文件名和类名要一致。我就在这被坑好几个小时!!!

卧槽

我写的类跟DoDoBook博主写的差不多,只不过封装了下,公司项目ThinkPHP 3.2.1,理论上 TP 3.2以上版本都可以直接拿去用(不是急于做项目的话,还是推荐研究下原理。其实这个文件也没啥研究的。。。)

还有就是听DoDoBook博主说官方下载的php包没什么用,虽然可以拿去用,但是还是推荐封装成类,就一个类文件,很简便。。

我把我的代码贴出来。。首先博主把类文件封装起来,放进类文件指定位置,只需要改下 $app_key 和 $master_secret:

文件路径为:ThinkPHP/Library/Org/Util/Jpush.class.php

<?php
//极光推送的类
//文档见:http://docs.jpush.cn/display/dev/Push-API-v3

/***使用示例
$pushObj = new Jpush();
//组装需要的参数
//$receive = 'all';       //全部
//$receive = array('tag'=>array('2401','2588','9527'));       //标签
$receive = array('alias'=>array('93d**************1'));    //别名
$content = '这是一个测试的推送数据....测试....Hello World...';
$m_type = 'http';
$m_txt = 'http://blog.kilvn.com/'; //可以留空
$m_time = '600';      //离线保留时间

//调用推送,并处理
$result = $pushObj->push($receive,$content,$m_type,$m_txt,$m_time);
if($result){
$res_arr = json_decode($result, true);
if(isset($res_arr['error'])){                 //如果返回了error则证明失败
echo $res_arr['error']['message'];       //错误信息
echo $res_arr['error']['code'];             //错误码
return false;
}else{
//处理成功的推送......
echo '推送成功.....';
return true;
}
}else{    //接口调用失败或无响应
echo '接口调用失败或无响应';
return false;
}
 ***/
namespace Org\Util;

class Jpush{

   private $app_key = 'b5b1e48b*********c058987';       //待发送的应用程序(appKey),只能填一个。
   private $master_secret = 'abf30c5********3122cf3';      //主密码
   private $url = "https://api.jpush.cn/v3/push";    //推送的地址

   //若实例化的时候传入相应的值则按新的相应值进行
   public function __construct($app_key=null, $master_secret=null,$url=null) {
      if ($app_key) $this->app_key = $app_key;
      if ($master_secret) $this->master_secret = $master_secret;
      if ($url) $this->url = $url;
   }

   /*  $receiver 接收者的信息
      all 字符串 该产品下面的所有用户. 对app_key下的所有用户推送消息
      tag(20个)Array标签组(并集): tag=>array('昆明','北京','曲靖','上海');
      tag_and(20个)Array标签组(交集): tag_and=>array('广州','女');
      alias(1000)Array别名(并集):    alias=>array('9**********88497f501','60********310');
      registration_id(1000)注册ID设备标识(并集): registration_id=>array('20ef********************ed39e');
   */
   //$content 推送的内容。
   //$m_type 推送附加字段的类型(可不填) http,tips,chat....
   //$m_txt 推送附加字段的类型对应的内容(可不填) 可能是url,可能是一段文字。
   //$m_time 保存离线时间的秒数默认为一天(可不传)单位为秒
   public function push($receiver='all',$content='',$m_type='',$m_txt='',$m_time='86400'){
      $base64=base64_encode("$this->app_key:$this->master_secret");
      $header=array("Authorization:Basic $base64","Content-Type:application/json");
      $data = array();
      $data['platform'] = 'all';       //目标用户终端手机的平台类型android,ios,winphone
      $data['audience'] = $receiver;    //目标用户

      $data['notification'] = array(
         //统一的模式--标准模式
         "alert"=>$content,
         //安卓自定义
         "android"=>array(
            "alert"=>$content,
            "title"=>"",
            "builder_id"=>1,
            "extras"=>array("type"=>$m_type, "txt"=>$m_txt)
         ),
         //ios的自定义
         "ios"=>array(
            "alert"=>$content,
            "badge"=>"1",
            "sound"=>"default",
            "extras"=>array("type"=>$m_type, "txt"=>$m_txt)
         ),
      );

      //苹果自定义---为了弹出值方便调测
      $data['message'] = array(
         "msg_content"=>$content,
         "extras"=>array("type"=>$m_type, "txt"=>$m_txt)
      );

      //附加选项
      $data['options'] = array(
         "sendno"=>time(),
         "time_to_live"=>$m_time,   //保存离线时间的秒数默认为一天
         "apns_production"=>1,     //指定 APNS 通知发送环境:0开发环境,1生产环境。
      );
      $param = json_encode($data);
      $res = $this->push_curl($param,$header);

      if($res){     //得到返回值--成功已否后面判断
         return $res;
      }else{       //未得到返回值--返回失败
         return false;
      }
   }

   //推送的Curl方法
   public function push_curl($param="",$header="") {
      if (empty($param)) { return false; }
      $postUrl = $this->url;
      $curlPost = $param;
      $ch = curl_init();                            //初始化curl
      curl_setopt($ch, CURLOPT_URL,$postUrl);                //抓取指定网页
      curl_setopt($ch, CURLOPT_HEADER, 0);               //设置header
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);         //要求结果为字符串且输出到屏幕上
      curl_setopt($ch, CURLOPT_POST, 1);                //post提交方式
      curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
      curl_setopt($ch, CURLOPT_HTTPHEADER,$header);        // 增加 HTTP Header(头)里的字段 
      curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);      // 终止从服务端进行验证
      curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
      $data = curl_exec($ch);                            //运行curl
      curl_close($ch);
      return $data;
   }
}

代码 1 结束。

$app_key是你项目的KEY,$master_secret是KEY的校验密码,在极光后台获取。跟安卓沟通了下,他那里只需要KEY,所以想了想,应该是服务器端需要校验KEY和密码,而接收端不需要校验密码。

代码中的命名空间namespace Org\Util;是为了封装类用的,如果在其他php项目不想封装类,注释此行。

然后在要使用的文件中引用代码1文件,实例化类 就能用了,不过我的项目只需要用户ID和内容,我又封装了下。。看代码2。。

/**
 * 极光推送类公共处理
 * @param $uid
 * @param $pushText
 * @return bool
 * by http://blog.kilvn.com/jpush-v3-php-demo/
 */
private function JpushApi($uid, $pushText){
    $pushObj = new \Org\Util\Jpush();
    //组装需要的参数
    //$receive = 'all'; //全部
    //$receive = array('tag'=>array('2401','2588','9527'));      //标签
    $receive = array('alias'=>array('kilvnblog_'.$uid));    //别名
    $content = $pushText;
    $m_type = 'http';
    $m_txt = '';
    $m_time = '600';        //离线保留时间

    //调用推送,并处理
    $result = $pushObj->push($receive,$content,$m_type,$m_txt,$m_time);
    if($result){
        $res_arr = json_decode($result, true);
        if(isset($res_arr['error'])){                       //如果返回了error则证明失败
            //echo $res_arr['error']['message'];          //错误信息
            //echo $res_arr['error']['code'];             //错误码
            return false;
        }else{
            //处理成功的推送......
            //echo '推送成功.....';
            return true;
        }
    }else{      //接口调用失败或无响应
        //echo '接口调用失败或无响应';
        return false;
    }
}

代码 2 结束。

使用的时候实例化对象即可。比如:

$uid = '55';
$pushText = '某某房探已帮您找到房东电话,请进入客户端确认。';
$status = $this->JpushApi($uid, $pushText);
if($status == true){
    $this->ajaxReturn(1); //判断返回值是true即推送成功
}else{
    $this->ajaxReturn(0);
}

代码 3 结束。

代码2和3在一个文件内。

需要注意的是$receive = array('alias'=>array('kilvnblog_'.$uid));,我是用的是别名alias,指定一个UID,每个安卓客户端在刚开始运行的时候都要向极光注册下这个ID,服务器端推送的时候如果这个ID不存在,那么会返回失败,没有找到推送对象。每个手机的ID唯一的,当某个用户(手机端)有了动态后,向他推送(指定是他,为不是所有的安卓端)。

'kilvnblog_'.$uid($uid 我传入的是一个数字ID,即用户ID)这个格式是我跟APP端约定好的,要保持一致。你可以自定义。

写完了。。节省了我N个小时呀。。(快被自己蠢哭了。。)有机会再研究下百度云推送。。

声明:欢迎转载,转载请注明来源:东子博客。  本文地址链接:http://blog.kilvn.com/jpush-v3-php-demo/

发表我的评论
取消评论
表情 每日打卡 贴图 链接 私密消息

Hi,您需要填写昵称和邮箱!

  • 昵称
  • 邮箱
  • 网址