PHP微信公号开发搭建

PHP微信公号开发搭建

PHP微信公号开发搭建

代码基于ThinkPHP5.0


控制器

class Wechat extends Controller
{

    public function index(){
        define("TOKEN","parkhunt");
        $this->responseMsg();
    }

    /**
     * 接入开发者模式验证
     */
    public function valid(){
        $echoStr = input("get.echostr");
        //valid signature , option
        if ($this->checkSignature()) {
            echo $echoStr;
            exit;
        }
    }

    public function responseMsg(){
        $postStr = file_get_contents("php://input");
        if(!empty($postStr)){
            $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
            $fromUsername = $postObj->FromUserName."";
            $toUsername = $postObj->ToUserName."";
            $msgType = $postObj->MsgType."";

            $userID = UWeiXin::checkUser($fromUsername);
            if(!$userID){
                UWeiXin::responseTextMsg($toUsername,$fromUsername,"用户信息异常!");
                return false;
            }
            switch ($msgType){
                case "text":
                    UWeiXin::responseTextMsg($toUsername,$fromUsername,"欢迎关注!");
                    break ;
                case "image":
                    break ;
                case "video":
                    break;
                case "event":
                    $Event = trim($postObj->Event."");
                    if ($Event == 'subscribe'){//关注
                        $EventKey = $postObj->EventKey."";
                        if(!empty($EventKey)){
                            $EventKeys = explode("_",$EventKey);
                            $EventKey = $EventKeys[1];
                        }else{
                            $EventKey = false;
                        }
                        if(is_numeric($EventKey) == true){//扫描二维码关注
                            UQrCodeHandle::handle($EventKey, $userID, $toUsername, $fromUsername,1);
                        }else{//正常关注
                            UWeiXin::subscribe($userID, $toUsername, $fromUsername);
                        }
                    }else if ($Event == 'unsubscribe'){//取消关注
                        UWeiXin::unsubscribe($userID);
                    }else if ($Event == 'CLICK') {//点击自定义菜单
                        $EventKey = trim($postObj->EventKey);

                    }else if($Event == 'LOCATION'){
                        $Longitude  = trim($postObj->Longitude);//经度
                        $Latitude = trim($postObj->Latitude);//纬度
                        $Longitude = $Longitude + 0.012576;
                        $Latitude = $Latitude + 0.007230;
                        UWeiXin::updateUserLocation($userID,$Longitude,$Latitude);

                    }else if ($Event == 'SCAN'){ //已关注扫描二维码
                        $EventKey = trim($postObj->EventKey);
                        UQrCodeHandle::handle($EventKey, $userID, $toUsername, $fromUsername, 0);
                    }
                    break;
                case "unsubscribe":
                    break;
                case "voice":
                    break;
                case "location":
                    break;
            }
        }else{
            $this->valid();
        }
    }


    private function checkSignature(){
        $signature = input("get.signature");
        $timestamp = input("get.timestamp");
        $nonce = input("get.nonce");
        $token = TOKEN;
        $tmpArr = array($token, $timestamp, $nonce);
        sort($tmpArr);
        $tmpStr = implode($tmpArr);
        $tmpStr = sha1($tmpStr);
        if ($tmpStr == $signature) {
            return true;
        } else {
            return false;
        }
    }

    /**
     * 设置自定义菜单
     */
    function setMenu(){
        $appID = config("WX_APPID");
        $ACCESS_TOKEN = UWeChat::getToken();
        $data = '{
       "button":[
          {
           "type":"view",
           "name":"首页",
           "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appID.
           '&redirect_uri=yoururl&response_type=code&scope=snsapi_base&state=netvii#wechat_redirect"
          },
         {
           "type":"view",
           "name":"发现",
           "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appID.
           '&redirect_uri=yoururl&response_type=code&scope=snsapi_base&state=netvii#wechat_redirect"
          },
          {
              "name":"更多",
              "sub_button": [
                {
                    "type": "view", 
                    "name": "个人中心", 
                    "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appID.
                    '&redirect_uri=yoururl&response_type=code&scope=snsapi_base&state=netvii#wechat_redirect"
                 }, 
                {
                    "type": "view", 
                    "name": "下载APP", 
                    "url":"https://open.weixin.qq.com/connect/oauth2/authorize?appid='.$appID.
                    '&redirect_uri=yoururl&response_type=code&scope=snsapi_base&state=netvii#wechat_redirect"
                }
             }
   ]}';

        $result = UNet::curl("https://api.weixin.qq.com/cgi-bin/menu/create?access_token={$ACCESS_TOKEN}", $data);
        echo $result;
    }

}


微信机器人工具类

/**
 * 微信机器人工具类
 * Class UWeiXin
 * @package app\common\utils
 */
class UWeiXin{

    /**
     * 检查用户
     * @param string $openID
     * @return bool|mixed
     */
    public function checkUser($openID=''){
        if(empty($openID)){
            return false;
        }
        $user["open_id"] = $openID;
        $userInfo = model("User")->where($user)->find();
        if(empty($userInfo)){
            $wxInfo = UWeChat::getUserInfo($openID);
            if(!$wxInfo){
                return false;
            }else{
                $where['union_id'] = $wxInfo['unionid'];
                $userInfo = model("User")->where($where)->find();
                if(empty($userInfo)){
                    $add["open_id"] = $openID;
                    $add["union_id"] = $wxInfo['unionid'];
                    $add["join_time"] = time();
                    $add["last_time"] = time();
                    $userID = model("User")->add($add);
                }else{
                    $save['last_time'] = time();
                    $save['status'] = 0;
                    $save["open_id"] = $openID;
                    model("User")->save($save,['id'=>$userInfo->id]);
                    $userID = $userInfo->id;
                }
            }
        }else{
            $save['last_time'] = time();
            $save['status'] = 0;
            model("User")->save($save,['id'=>$userInfo->id]);
            $userID = $userInfo->id;
        }
        return $userID;
    }


    /**
     * 用户关注
     * @param $userID
     * @param $toUsername 微信原始ID
     * @param $fromUsername 用户OpenID 扫码人的微信openID
     */
    public function subscribe($userID, $toUsername, $fromUsername){
//        $save["status"] = 0;
//        model("User")->save($save,['id'=>$userID]);
        $text = getConfigValue("welcome_info");
        $this->responseTextMsg($toUsername,$fromUsername,$text);
    }


    /**
     * 用户取消关注
     * @param $userID
     */
    public function unsubscribe($userID){
        $save["status"] = 1;
        model("User")->save($save,['id'=>$userID]);
    }


    /**
     * 更新用户经纬度
     */
    public function updateUserLocation($userID, $long, $lat){
        $save["xpoint"] = $long;
        $save["ypoint"] = $lat;
        model("User")->save($save,['id'=>$userID]);
    }



    /**
     * 响应文字消息
     */
    public function responseTextMsg($toUsername,$fromUsername,$content){
        $cur_time = time();
        $resultStr = "<xml>";
        $resultStr .= "<ToUserName><![CDATA[".$fromUsername."]]></ToUserName>";
        $resultStr .= "<FromUserName><![CDATA[".$toUsername."]]></FromUserName>";
        $resultStr .= "<CreateTime>".$cur_time."</CreateTime>";
        $resultStr .= "<MsgType><![CDATA[text]]></MsgType>";
        $resultStr .= "<Content><![CDATA[".$content."]]></Content>";
        $resultStr .= "<FuncFlag>0</FuncFlag>";
        $resultStr .= "</xml>";
        echo $resultStr;
    }

    /**
     * 添加图文消息
     */
    public function addMsgItem($title, $desc, $pic_url, $link) {
        $itemStr = "<item>\n";
        $itemStr .= "<Title><![CDATA[".$title."]]></Title>\n";
        $itemStr .= "<Description><![CDATA[".$desc."]]></Description>\n";
        $itemStr .= "<PicUrl><![CDATA[".$pic_url."]]></PicUrl>\n";
        $itemStr .= "<Url><![CDATA[".$link."]]></Url>\n";
        $itemStr .= "</item>\n";
        return $itemStr;
    }

    /**
     * 响应图文消息
     */
    public function responseImgTextMsg($toUsername,$fromUsername,$data){
        $cur_time = time();
        $resultStr = "<xml>";
        $resultStr .= "<ToUserName><![CDATA[".$fromUsername."]]></ToUserName>";
        $resultStr .= "<FromUserName><![CDATA[".$toUsername."]]></FromUserName>";
        $resultStr .= "<CreateTime>".$cur_time."</CreateTime>";
        $resultStr .= "<MsgType><![CDATA[news]]></MsgType>";
        $resultStr .= "<ArticleCount><![CDATA[".count($data)."]]></ArticleCount>";
        $resultStr .= "<Articles>";

        foreach ($data as $value) {
            $resultStr .= $value;
        }
        $resultStr .= "</Articles>";
        $resultStr .= "<FuncFlag>1</FuncFlag>";
        $resultStr .= "</xml>";
        echo $resultStr;
    }




}


微信接口工具类

/**
 * 微信接口工具类
 * Class UWeChat
 * @package app\common\utils
 */
class UWeChat
{
 /**
     *  获取access_token
     * @return mixed
     */
 public function getToken(){
 $fileUrl = App::getRuntimePath()."access_token.json";
 if(file_exists($fileUrl)){
 $oldToken = json_decode(file_get_contents(App::getRuntimePath()."/access_token.json"),true);
        }else{
 $oldToken = "";
        }
 $time = time();
 if(empty($oldToken["access_token"]) ||  $time - $oldToken["time"] > 1800){
 $appid = config("WX_APPID");
 $secret = config("WX_SECRET");
 $token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$secret}";
 $json = UNet::curl($token_url,null);
 $result = json_decode($json,TRUE);
 $result["time"] = time();
 file_put_contents(App::getRuntimePath()."/access_token.json",json_encode($result));
        }else{
 $result["access_token"] = $oldToken["access_token"];
        }
 if(empty($result["access_token"])){
 return false;
        }
 return $result["access_token"];
    }


 /**
     *  授权登录-获取token
     * @param $code
     * @return mixed
     */
 public function getAuthToken($code){
 $appid = config("WX_APPID");
 $secret = config("WX_SECRET");
 $getTokenUrl = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$appid}&secret={$secret}&code={$code}&grant_type=authorization_code";
 $tokenResult = UNet::curl($getTokenUrl,null);
 return json_decode($tokenResult,true);
    }

 /**
     *  获取用户信息-已关注
     * @param $wxID
     * @return mixed
     */
 public function getUserInfo($wxID){
 $access_token = $this->getToken();
 if(!$access_token){
 return false;
        }
 $userInfoUrl = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=$access_token&openid=$wxID";
 $userInfoResult = UNet::curl($userInfoUrl,null);
 return json_decode($userInfoResult,true);
    }

 /**
     *  获取用户信息-授权登录
     * @param $tokenInfo
     * @return mixed
     */
 public function getUserInfoForAuth($tokenInfo){
 $userInfoUrl = "https://api.weixin.qq.com/sns/userinfo?access_token=".$tokenInfo["access_token"]."&openid=".$tokenInfo["openid"]."&lang=zh_CN";
 $userInfoResult = UNet::curl($userInfoUrl,null);
 return json_decode($userInfoResult,true);
    }



 /**
     * 调用临时场景ID及临时二维码
     * @param $target 分类
     * @param $target_id 分类ID
     * @return int|string
     */
 public function getTempQrCode($target,$target_id){
 $sceneID = $this->getTempSceneID($target,$target_id);
 return $this->getCodeImgTemp($sceneID);
    }

 /**
     * 获取临时sceneID
     * @param $target 分类
     * @param $target_id 分类ID
     * @return int
     */
 public function getTempSceneID($target,$target_id){
 $codeInfo = Db::table("temp_qr_code")
            ->where("target",$target)
            ->where("target_id",$target_id)
            ->find();
 if(empty($codeInfo)){
 $sceneID = rand(10000001,99999999);
 $res = Db::table("temp_qr_code")
                ->where("scene_id",$sceneID)
                ->find();
 if(empty($res)){
                Db::table("temp_qr_code")
                    ->insertGetId(
                        ['target'=>$target,'target_id'=>$target_id,'scene_id'=>$sceneID,'validTime'=>time()+2592000]
                    );
            }else{
 if($res['validTime'] < time()){
                    Db::table("temp_qr_code")
                        ->where("id",$res['id'])
                        ->update(['validTime'=>time()+2592000]);
                }else{
 $this->getTempSceneID($target,$target_id);
                }
            }
        }else{
            Db::table("temp_qr_code")
                ->where("id",$codeInfo['id'])
                ->update(['validTime'=>time()+2592000]);
 $sceneID = $codeInfo['scene_id'];
        }
 return $sceneID;
    }


 /**
     * 获取临时二维码
     * @param $sceneID 场景ID
     */
 public function getCodeImgTemp($sceneID){
 if(empty($sceneID) || $sceneID == 0){
 return false;
        }
 $data = '{"expire_seconds":2592000,"action_name":"QR_SCENE","action_info":{"scene":{"scene_id":'.$sceneID.'}}}';
 $access_token = $this->getToken();
 $get_img_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=".$access_token;
 $result = UNet::curl($get_img_url,$data);
 $jsonResult = json_decode($result,true);
 file_put_contents(App::getRuntimePath()."code.json",$jsonResult);
 if(isset($jsonResult['ticket'])){
 $ticket = urlencode($jsonResult['ticket']);
        }
 if(empty($ticket)){
 return false;
        }
 $get_ticket_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=$ticket";
 return $get_ticket_url;
    }



 public function  getLongQrCode($target,$target_id){ //调用永久场景ID及永久二维码
 $result = $this->sceneID($target,$target_id);
 return $this->getCodeImgLong($result);
    }


 public function sceneID($target,$target_id){ //获取永久场景ID
 $where["target"] = $target;
 $where["target_id"] = $target_id;
 $result = Db::table("qr_code")->where($where)->find();
 if(empty($result)){
 $sceneID = rand(1,100000);
 $hasData = Db::table("qr_code")->where("scene_id=".$sceneID)->find();
 if(empty($hasData)){
 $add["target"] = $target;
 $add["target_id"] = $target_id;
 $add["scene_id"] = $sceneID;
                Db::table("qr_code")->insert($add);
 return $sceneID;
            }else{
                sceneID($target,$target_id);
            }
        }else{
 return $result["scene_id"];
        }
    }


 public   function getCodeImgLong($sceneID){ //获取永久二维码
 if (empty($sceneID) || $sceneID == 0) {
 return false;
        }
 $data = '{"action_name": "QR_LIMIT_SCENE", "action_info": {"scene": {"scene_id": '.$sceneID.'}}}';
 $access_token = $this->getToken();

 $get_img_url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token={$access_token}";
 $result = UNet::curl($get_img_url,$data);

 $jsonResult = json_decode($result,TRUE);
 if (!isset($jsonResult['ticket'])) {
 return false;
        }
 $ticket = urlencode($jsonResult['ticket']);
 $get_ticket_url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=$ticket";
 return $get_ticket_url;
    }


 //发送客服消息
 public function  sendMsg($data){
 $token = $this->getToken();
 for($i=0;$i<count($data);$i++){
 $json = stripslashes($data[$i]);
 $url = "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token={$token}";
 $tmpInfo =  UNet::curl($url,$json);
        }
 return $tmpInfo;
    }
 //发送文字客服消息
 public function sendText($openID,$content){
 $arr = array();
 $msg = '{
              "touser":"'.$openID.'",
              "msgtype":"text",
              "text":
              {
              "content":"'.$content.'"
              }
            }';
 array_push($arr,$msg);
 return $this->sendMsg($arr);
    }

 //推送单图文客服消息
 public function sendImgText($openID,$title,$content,$url,$img){
 $arr = array();
 $msg  = '{
           "touser":"'.$openID.'",
           "msgtype":"news",
           "news":{
                  "articles":[{
                         "title":"'.$title.'",
                         "description":"'.$content.'",
                         "url":"'.$url.'",
                         "picurl":"'.$img.'"
                   }]
            }

            }';
 array_push($arr,$msg);
 return $this->sendMsg($arr);
    }
 //推送多图文客服消息
 public function sendManyImgText($openID,$data){
 $arr = array();
 $msg  = '{
           "touser":"'.$openID.'",
           "msgtype":"news",
           "news":{';
 foreach ($data as $k=>$v){
 $msg .= '"articles":[{
                         "title":"'.$v["title"].'",
                         "description":"'.$v["content"].'",
                         "url":"'.$v["url"].'",
                         "picurl":"'.$v["img"].'"
                   }]';
 if($k != (count($data) - 1)){
 $msg .= ",";
            }
        }
 $msg .= '}

            }';
 array_push($arr,$msg);
 return $this->sendMsg($arr);
    }