做这个功能,要处理的东西挺多的,步骤如下

  参考来源:http://t.zoukankan.com/kenshinobiy-p-10787215.html

  1、  需要有两个公众号,一个服务号,一个订阅号。(都需要认证的)

    服务号有网页授权接口,用户授权后获取用户的openid,通过用户的openid获取用户的信息,用户的信息里包含用户对公众号的关注字段。

    但是,订阅号没有相应的网页授权接口权限,无法从通过相应的接口来获取openid

 

  2、两个公众号都要绑定在微信开放平台,绑定平台后,用户可通过openid获取统一的unionid,不绑定开放平台没有unionID字段

    1)自己的后台先获取订阅号所有用户的openid,通过openid获取用户信息(包含unionid),保存入库。

    官方地址:https://developers.weixin.qq.com/doc/offiaccount/User_Management/Get_users_basic_information_UnionID.html#UinonId

//获取access_token接口
https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$this->appid.'&secret='.$this->appsecret
//获取openid接口
$url = 'https://api.weixin.qq.com/cgi-bin/user/get?access_token='.$access_token.'&next_openid='.$this->next_openid
//批量获取用户信息接口
https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token='.$access_token

  


    2)前端授权获取服务号的openid再获取用户信息(包含unionid,这个unionID和订阅号的是一样的),发送给后台,对比数据库的unionID是否一致可判断用户是否关注订阅号

 

    3)订阅号,开启服务器配置功能,先验证token,再写接收用户关注和取消关注的代码,用户关注则添加该用户的信息(包含unionID),反之删除。

    

<?php
use think\Db;
use think\Request;

define("TOKEN", "12345");//定义识别码,自己在公众号后台设定值
$wechatObj = new ggg();//实例化ggg类
if(!isset($_GET["echostr"])){
    $wechatObj->getinfo();
}else{
    $wechatObj->valid();
}
class ggg
{
    //  验证token
    public function valid()
    {
       $echoStr = $_GET["echostr"];
        //valid signature , option
        // 验证成功的话,就exit退出
        if($this->checkSignature()){
        	echo $echoStr;
        	exit;
        }
      }
    //  验证token
    private function checkSignature()
    {
      $signature = $_GET["signature"];
      $timestamp = $_GET["timestamp"];
      $nonce = $_GET["nonce"];
      $token = TOKEN;
      $tmpArr = array($token, $timestamp, $nonce);
      sort($tmpArr, SORT_STRING);
      $tmpStr = implode( $tmpArr );
      $tmpStr = sha1( $tmpStr );
      if( $tmpStr == $signature ){
       return true;
      }else{
       return false;
      }
    }
    
    // 获取用户关注取消公众号信息
    public function getinfo(){
    	$data = input();
    	$time=date('m_d-H_i_s',time());
    	$postStr = isset($GLOBALS['HTTP_RAW_POST_DATA']) ? $GLOBALS['HTTP_RAW_POST_DATA'] : file_get_contents("php://input");
    	if (!empty($postStr)){
            $objectxml = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);//将文件转换成 对象
            $datas = array();
            foreach ($objectxml as $k => $v) {
                $datas[(string) $k] = (string) $v;
            }
            file_put_contents($time.'gz.txt',json_encode($datas));
        	//用户关注和取消关注事件
                //获取用户openID,用openID查询出unionid,保存数据到数据库 	
        	if(isset($datas['Event'])){
        	    if($datas['Event'] == 'subscribe'){
        	    // FromUserName就是openid
                    $userdata=$this->getUserGzInfo($datas['FromUserName']);
                    file_put_contents($time.'gz_add.txt',json_encode($userdata));
                    $this->adduser($userdata);
                }
                if($datas['Event'] == 'unsubscribe'){
                    $userdata=$this->getUserGzInfo($datas['FromUserName']);
                    file_put_contents($time.'gz_del.txt',json_encode($userdata));
                    $this->deluser($userdata);
                }
                exit;
            }
    	}else {
            exit;
        }
        
    }

    // 获取用户信息
    public function getUserGzInfo($openid){
        $postData = input();
    	$ACCESS_TOKEN = $this->getAccessToken();
    	$userInfoUrl = 'https://api.weixin.qq.com/cgi-bin/user/info?access_token='.$ACCESS_TOKEN.'&openid='.$openid.'&lang=zh_CN';
        $userInfo = $this->request_get($userInfoUrl);
        $userInfo = json_decode($userInfo,true);
        return $userInfo;
        // successMsg('成功',userInfo);
    }
    // 获取accesstoken
    public function getAccessToken(){
        $appid = 'wxaa95f05514ab8e96';
        $secret = '65955ea0eb0c599c8badd746ee26bb5c';
        //获取token
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$appid.'&secret='.$secret;
        $ret = $this->request_get($url);
        if($ret == false){
            return false;
        }
        $ret = @json_decode($ret,true);
        return $ret['access_token'];
    }
    public function request_get($url){
        // php请求接口并将返回数据进行json化的函数
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }
    // 添加用户数据
    public function adduser($data){
        $DB = Db::connect([
          // 数据库类型
          'type'      => '',
          // 服务器地址
          'hostname'    => '',
          // 数据库名
          'database'    => '',
          // 用户名
          'username'    => '',
          // 密码
          'password'    => '',
          // 端口
          'hostport'    => '',
        ]);
        $res='';
        if($data['unionid']){
            // $findata=$DB->table('表')->where('unionid',$data)->find();
            $da=['openid'=>$data['openid'],'sex'=>$data['sex'],'unionid'=>$data['unionid'],'time'=>time()];
            // file_put_contents(time().'gz5.txt',json_encode($da));
            $res=$DB->table('userzzs')->insert($da);
        }
        return $res;
    }
    // 删除用户
    public function deluser($data){
        $DB = Db::connect([
          // 数据库类型
          'type'      => '',
          // 服务器地址
          'hostname'    => '',
          // 数据库名
          'database'    => '',
          // 用户名
          'username'    => '',
          // 密码
          'password'    => '',
          // 端口
          'hostport'    => '',
        ]);
        $res='';
        if($data['openid']){
            $res=$DB->table('表')->where('openid',$data['openid'])->delete();
        }
        return $res;
    }

}

  

  大致完成!