1.QQ封装类
<?php
class QQ{
    public static $version = "2.0";
    public static $getAuthCodeUrl = "https://graph.qq.com/oauth2.0/authorize";
    public static $getAccessTokenUrl = "https://graph.qq.com/oauth2.0/token";
    public static $getOpenIDUrl = "https://graph.qq.com/oauth2.0/me";
    public static $getUserInfoUrl = "https://graph.qq.com/user/get_user_info";
    public static function do_post($url, $data){
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE); 
        curl_setopt($ch, CURLOPT_POST, TRUE); 
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data); 
        curl_setopt($ch, CURLOPT_URL, $url);
        $ret = curl_exec($ch);

        curl_close($ch);
        return $ret;
    }
    public static function get_url_contents($url){
        if (ini_get("allow_url_fopen") == "1")
            return file_get_contents($url);

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
        curl_setopt($ch, CURLOPT_URL, $url);
        $result =  curl_exec($ch);
        curl_close($ch);

        return $result;
    }
    public static function combineURL($baseURL,$keysArr){
        $combined = $baseURL."?";
        $valueArr = [];
        foreach($keysArr as $key => $val){
            $valueArr[] = "$key=$val";
        }
        $keyStr = implode("&",$valueArr);
        $combined .= ($keyStr);
        return $combined;
    }
    public $config;
    public function setSession($key,$val){
        session_start();
        if(!array_key_exists('QQOauth', $_SESSION))
            $_SESSION['QQOauth']=[];
        $_SESSION['QQOauth'][$key]=$val;
    }
    public function getSession($key){
        session_start();
        if(!array_key_exists('QQOauth', $_SESSION))
            $_SESSION['QQOauth']=[];
        if(array_key_exists($key, $_SESSION['QQOauth']))
            return $_SESSION['QQOauth'][$key];
        return false;
    }
    public function __construct($config){
        $this->config=$config;
    }
    public function getAuthCode(){
        $appid = $this->config["appid"];
        $callback = $this->config["callback"];
        $scope = "get_user_info";
        //-------生成唯一随机串防CSRF攻击
        $state = md5(uniqid(rand(), TRUE));
        $this->setSession("state",$state);
        //-------构造请求参数列表
        $keysArr = [
            "response_type" => "code",
            "client_id" => $appid,
            "redirect_uri" => $callback,
            "state" => $state,
            "scope" => $scope
        ];
        $login_url =  self::combineURL(self::$getAuthCodeUrl, $keysArr);
        return $login_url;
    }
    public function getAccessToken($code,$state){
        // $states = $this->getSession("state");
        //--------验证state防止CSRF攻击
        // if(!$states || $states != $state){
        //  return false;
        // }
        //-------请求参数列表
        $keysArr = [
            "grant_type" => "authorization_code",
            "client_id" => $this->config["appid"],
            "redirect_uri" => urlencode($this->config["callback"]),
            "client_secret" => $this->config["appkey"],
            "code" => $code
        ];
        //------构造请求access_token的url
        $token_url = self::combineURL(self::$getAccessTokenUrl, $keysArr);
        $response = self::get_url_contents($token_url);
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response  = substr($response, $lpos + 1, $rpos - $lpos -1);
            $msg = json_decode($response);
            if(isset($msg->error)){
                return false;
            }
        }
        $params = [];
        parse_str($response, $params);
        return $params["access_token"];
    }
    public function getOpenID($access_token){
        //-------请求参数列表
        $keysArr = ["access_token" => $access_token];
        $graph_url = self::combineURL(self::$getOpenIDUrl, $keysArr);
        $response = self::get_url_contents($graph_url);
        //--------检测错误是否发生
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos -1);
        }
        $user = json_decode($response);
        if(isset($user->error)){
            return false;
        }
        return $user->openid;
    }
    public function getUserInfo($access_token,$openid){
        //-------请求参数列表
        $appid = $this->config["appid"];
        $keysArr = [
            "access_token" => $access_token,
            "oauth_consumer_key" => $appid,
            "openid" => $openid
        ];
        $graph_url = self::combineURL(self::$getUserInfoUrl, $keysArr);
        $response = self::get_url_contents($graph_url);
        //--------检测错误是否发生
        if(strpos($response, "callback") !== false){
            $lpos = strpos($response, "(");
            $rpos = strrpos($response, ")");
            $response = substr($response, $lpos + 1, $rpos - $lpos -1);
        }
        $user = json_decode($response);
        if(isset($user->error)){
            return false;
        }
        return $user;
    }
}
   2. 控制器代码
    //qq第三方登陆ak
    private $qq;
    private $qqConfig=[
        'appid'=>"********",
        'appkey'=>"**************************",
        'callback'=>"http://www.baidu.com/thinkphp/public/index.php/bshy_web/user/notify" //回调地址
    ];
    function __construct(){
        parent::__construct();
        vendor("qqconnect.QQ");
        $qqConfig = $this->qqConfig;
        //$qqConfig['callback']=url("http://www.baidu.com/thinkphp/public/index.php/bshy_web/user/notify",false,true,true);
        $this->qq = new \QQ($qqConfig);
    }
    //获取QQ二维码
    public function qqLogin(){
        $response = request();
        $data = $response->param();
        if(!empty($data['uid'])){
            Cache::set('uid',$data['uid']);  //存到Cache
        }
        $url = $this->qq->getAuthCode();
        //print_r($url);die;
        header("Location:".$url);
    }
    
    //QQ绑定的回调地址
    public function notify(){
        vendor("qqconnect.QQ");
        $param = $this->request->param();
        $code = $param['code'];
        $state = $param['state'];
        $qqConfig = $this->qqConfig;
        $qq = new \QQ($qqConfig);
        $accessToken = $qq->getAccessToken($code,$state);
        if(!$accessToken){
            $this->error("非法操作");
        }
        $openid = $qq->getOpenID($accessToken);
        //print_r($openid);die;
        //$tencent_userInfo=$qq->getUserInfo($accessToken,$openid);
        //$userInfo = json_decode(json_encode($tencent_userInfo),true);
        $userInfo['openid']=$openid;
        $userInfo['unionid']=$openid;
        $uid=Cache::get('uid');
        Cache::clear(); 
        if(!empty($uid)){
            $this->user_qq($userInfo,$uid);
        }else{
            $this->dealWithQqLogin($userInfo);
        }
    }
    
    /**
     * 根据QQ授权用户的信息 进行下一步的梳理
     * @param $user_info
     */
    public function dealWithQqLogin($user_info){
        //判断此微信是否在平台绑定
        $is_user=Db::name('ucenter_member')->where('qq_openid',$user_info['openid'])->where('qq_unionid',$user_info['unionid'])->find();
        //绑定直接登陆,没绑定注册
        if(!empty($is_user)){
            $token=build_auth_key();
            $array['token'] =$token;
            $array['token_time'] = time();
            $uid=$is_user['id'];
            Db::name('ucenter_member')->where('id',$uid)->update($array);
            header("Location: http://www.baidu.com/login?uid=$uid&token=$token&type=1");
        }else{
            header("Location: http://www.baidu.com/login?type=0&openid=".$user_info['openid']."&unionid=".$user_info['unionid']."&status=2");
        }
    }

 

    //个人中心绑定QQ
    public function user_qq($user_info,$uid){
        $array['qq_openid'] =$user_info['openid'];
        $array['qq_unionid'] = $user_info['unionid'];
        $token=Db::name('ucenter_member')->where('id',$uid)->value('token');
        $is_qq=Db::name('ucenter_member')->where('qq_openid',$user_info['openid'])->where('qq_unionid',$user_info['unionid'])->find();
        if(!empty($is_qq)){
            header("Location: http://www.baidu.com/person/user/userBind?uid=$uid&token=$token&type=2");
            die;
        }
        $re=Db::name('ucenter_member')->where('id',$uid)->update($array);
        if(!empty($re)){
            header("Location: http://www.baidu.com/person/user/userBind?uid=$uid&token=$token&type=1");
        }else{
            header("Location: http://www.baidu.com/person/user/userBind?uid=$uid&token=$token&type=0");
        }
    }

 

    //QQ解绑
    public function jie_qq(){
        $check_status = $this->status;
        if ($check_status != 200) {
            $msg = $this->msg;
            if ($check_status != 0) {
                $check_status = 2;
            } else {
                $check_status = 0;
            }
            return json(['status' => $check_status, 'msg' => $msg, 'info' => '']);
        }
        $data = $this->data;
        $status=1;
        $msg='解绑成功';
        $array['qq_openid'] ='';
        $array['qq_unionid'] = '';
        $info=Db::name('ucenter_member')->where('id',$data['uid'])->update($array);
        if(!$info){
            $status=0;
            $msg='解绑失败';
        }
        return json(['status'=>$status,'msg'=>$msg,'info'=>$info]);
    }