• 微信公众号图文回复验证码并写入数据库的基本思路


    接了个小活:要求公众号中用户回复1,公众号被动回复7位数验证码,同时把用户openId和验证码写入数据库

    简单写了各测试demo:工具 thinkphp   订阅号子钦有话说内申请的测试账号 

    接口配置信息修改

    Controller控制器   输入1得到被动回复验证码(里面大多数代码与标题无关,想必大家能用到,所以没有删除)

    <?php
    namespace HomeController;
    use HomeCommonCommonController;
    /**
     *@parame  微信公众号开发 
     */
    class WeChatController extends CommonController {
        //配置接口信息接入api
        public function index() {
            //1.获得参数 signature nonce token timestamp echostr
            $nonce     = $_GET['nonce'];
            $token     = 'zhangmangde';
            $timestamp = $_GET['timestamp'];
            $echostr   = $_GET['echostr'];
            $signature = $_GET['signature'];
            //2.拼成数组,然后按字典序排序
            $array     = array();
            $array     = array($nonce,$timestamp,$token);
            sort($array);
            //3.拼成字符串,sha1加密,然后和$signature进行比较
            $str = sha1(implode($array));
            if($str == $signature && $echostr){
                //第一次接入微信api的时候
                echo $echostr;
                exit;
            }else{
                $this->responseMsg();
            }
            
        }
        
        /*public function show(){
            echo 'zhangmangde';
        }*/
        //接受事件,推送并回复
        public function responseMsg(){
            //1.获取到微信推送过来的post数据(xml格式)
            $postArr = $GLOBALS['HTTP_RAW_POST_DATA'];
            //2.处理消息类型,并设置回复内容和类型
            /*<xml>
            <ToUserName><![CDATA[toUser]]></ToUserName>
            <FromUserName><![CDATA[FromUser]]></FromUserName>
            <CreateTime>123456789</CreateTime>
            <MsgType><![CDATA[event]]></MsgType>
            <Event><![CDATA[subscribe]]></Event>
            </xml>*/
            $postObj = simplexml_load_string($postArr);//将xml字符串载入对象中
            //$postObj->ToUserName = '';
            //$postObj->FromUserName = '';
            //$postObj->CreateTime = '';
            //$postObj->MsgType = '';
            //$postObj->Event = '';
            //判断该数据包是否是订阅的事件推送
            if(strtolower($postObj->MsgType) == 'event'){
                //如果是关注subcribe事件
                if(strtolower($postObj->Event) == 'subscribe'){
                    //回复用户消息
                    $arr  = array(
                        array(
                            'title'       => '欢迎关注子钦的公众号开发版哟^^~~^^',
                            'description' => '张子钦很酷哦 or ziqin is very cool 哈哈!关注有惊喜哦',
                            'picUrl'      => 'http://waphd.simufengyun.com/Public/Home/images/zmd123.png',
                            'url'         => 'http://wap.simufengyun.com/',
                        ),
                    );
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;//实例化时,一定要注意Model的路径问题 下面a()方法是测试路径问题
                    $weChatModel->responseSubscribe($postObj,$arr);//调用模型中的方法
                }    
                //点击事件
                if(strtolower($postObj->Event) == 'click'){
                    //如果是自定义菜单中的event->click
                    if(strtolower($postObj->EventKey) == 'item1'){
                        $content = "这是菜单一事件的推送";
                    }
                    if(strtolower($postObj->EventKey) == 'songs'){
                        $content = "这是歌曲事件的推送";
                    }
                    //实例化模型
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                //跳转事件
                if(strtolower($postObj->Event) == 'view'){
                    //如果是自定义菜单中的event->view
                    $content = "要跳转的链接是".$postObj->EventKey;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                //
                if(strtolower($postObj->Event) == 'SCAN'){
                    //自定义菜单中的event->scan
                    $content = "扫描场景".$postObj->EventKey;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'LOCATION'){
                    //自定义菜单中的event->LOCATION
                    $content = "上传位置:纬度".$postObj->Latitude.";经度".$postObj->Longitude;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'scancode_waitmsg'){
                    //自定义菜单中的event->scancode_waitmsg
                    $content = "扫描带提示:类型".$postObj->ScanCodeInfo->ScanType."结果:".$postObj->ScanCodeInfo->ScanResult;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'scancode_push'){
                    //自定义菜单中的event->scancode_push
                    $content = "扫码推事件";
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'pic_sysphoto'){
                    //自定义菜单中的event->pic_sysphoto
                    $content = "系统拍照";
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'pic_weixin'){
                    //自定义菜单中的event->pic_weixin
                    $content = "相册发图:数量".$postObj->SendPicsInfo->Count;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'pic_photo_or_album'){
                    //自定义菜单中的event->pic_photo_or_album
                    $content = "拍照或者相册:数量".$postObj->SendPicsInfo->Count;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
                if(strtolower($postObj->Event) == 'location_select'){
                    //自定义菜单中的event->location_select
                    $content = "发送位置:标签".$postObj->SendLocationInfo->Label;
                    //实例化模型
                    $weChatModel = new HomeModelWeChatModel;
                    $weChatModel->responseText($postObj,$content);//调用方法
                }
            }
            
            //判断是否是纯文本
            /*if(strtolower($postObj->MsgType) == 'text'){
                switch(trim($postObj->Content)){
                    case 1:
                        $content = '您输入的数字是1';
                    break;
                    case 2:
                        $content = '您输入的数字是2';
                    break;
                    case 3:
                        $content = '您输入的数字是3';
                    break;
                    case '英文':
                        $content = 'ziqin is very good';
                    break;
                    case '电话':
                        $content = '15236272691';
                    break;
                    case '百度':
                        $content = '<a href="https://www.baidu.com">百度搜索</a>';
                    break;
                }
                $template = "<xml>
                            <ToUserName><![CDATA[%s]]></ToUserName>
                            <FromUserName><![CDATA[%s]]></FromUserName>
                            <CreateTime>%s</CreateTime>
                            <MsgType><![CDATA[%s]]></MsgType>
                            <Content><![CDATA[%s]]></Content>
                            </xml>";
                $toUser   = $postObj->FromUserName;
                $fromUser = $postObj->ToUserName;
                $time     = time();
                $msgType  = 'text';
                echo sprintf($template,$toUser,$fromUser,$time,$msgType,$content);
            }*/
            
            //用户发送tuwen1关键字的时候,发送一个图文 或者发送纯文本  或者多图文
            if(strtolower($postObj->MsgType) == 'text' && trim($postObj->Content)=='tuwen1'){
                $arr  = array(
                    array(
                        'title'       => '私募风云网年度峰会报名开始啦',
                        'description' => 'ziqin is very cool',
                        'picUrl'      => 'http://wap.simufengyun.com//Public/Home/images/ban1.jpg',
                        'url'         => 'http://wap.simufengyun.com/',
                    ),
                    array(
                        'title'       => '私募风云网官方网站',
                        'description' => 'simufengyun is very cool',
                        'picUrl'      => 'http://wap.simufengyun.com//Public/Home/images/ban2.jpg',
                        'url'         => 'http://wap.simufengyun.com/',
                    ),
                    array(
                        'title'       => '我是子钦有话说',
                        'description' => 'ziqin is very cool',
                        'picUrl'      => 'http://wap.simufengyun.com//Public/Home/images/ban3.jpg',
                        'url'         => 'http://wap.simufengyun.com/',
                    ),
                );
                //实例化模型
                $weChatModel = new HomeModelWeChatModel;//实例化时,一定要注意Model的路径问题 下面a()方法是测试路径问题
                $weChatModel->responseNews($postObj,$arr);//调用模型中的方法
            }else{
                switch(trim($postObj->Content)){
                    case 1:
                          $openId = $postObj->FromUserName;//获取用户openId
              $content .= '您的验证码是:'.getsRandChar(7)."
    ";//回复随机7位数验证码 
              $content .='您的openId是:'.$openId;
              //此处可以操作写入数据库
    break; case 2: $content = '您输入的数字是2'; break; case 3: $content = '您输入的数字是3'; break; case 4: $content = '张'; break; case '英文': $content = 'ziqin is very good'; break; case '电话': $content = '15236272691'; break; case '百度': $content = '<a href="https://www.baidu.com">百度搜索</a>'; break; default: $content = "没有找到相关信息"; break; } //实例化模型 $weChatModel = new HomeModelWeChatModel; $weChatModel->responseText($postObj,$content);//调用方法 } } //接收事件消息 /* private function receiveEvent($object) { $content = ""; switch ($object->Event) { case "subscribe": $content = "欢迎关注方倍工作室 "; $content .= (!empty($object->EventKey))?(" 来自二维码场景 ".str_replace("qrscene_","",$object->EventKey)):""; break; case "unsubscribe": $content = "取消关注"; break; case "CLICK": switch ($object->EventKey) { case "COMPANY": $content = array(); $content[] = array("Title"=>"方倍工作室", "Description"=>"", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958"); break; default: $content = "点击菜单:".$object->EventKey; break; } break; case "VIEW": $content = "跳转链接 ".$object->EventKey; break; case "SCAN": $content = "扫描场景 ".$object->EventKey; break; case "LOCATION": $content = "上传位置:纬度 ".$object->Latitude.";经度 ".$object->Longitude; break; case "scancode_waitmsg": $content = "扫码带提示:类型 ".$object->ScanCodeInfo->ScanType." 结果:".$object->ScanCodeInfo->ScanResult; break; case "scancode_push": $content = "扫码推事件"; break; case "pic_sysphoto": $content = "系统拍照"; break; case "pic_weixin": $content = "相册发图:数量 ".$object->SendPicsInfo->Count; break; case "pic_photo_or_album": $content = "拍照或者相册:数量 ".$object->SendPicsInfo->Count; break; case "location_select": $content = "发送位置:标签 ".$object->SendLocationInfo->Label; break; default: $content = "receive a new event: ".$object->Event." 技术支持 方倍工作室"; break; } if(is_array($content)){ if (isset($content[0]['PicUrl'])){ $result = $this->transmitNews($object, $content); }else if (isset($content['MusicUrl'])){ $result = $this->transmitMusic($object, $content); } }else{ $result = $this->transmitText($object, $content); } return $result; }*/ //采集远程数据 /*function http_curl(){ //获取远程数据 //1.初始化curl $ch = curl_init(); $url = 'http://wap.simufengyun.com'; //2.设置curl参数 curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); //3.采集 $output = curl_exec($ch); //4.关闭 curl_close($ch); var_dump($output); }*/ /** *$url 接口url string *$type 请求类型 string *$res 返回数据类型 string *$arr post请求参数 string */ function http_curl($url,$type='get',$res='json',$arr=''){ //获取远程数据 //1.初始化curl $ch = curl_init(); //$url = 'http://wap.simufengyun.com'; //2.设置curl参数 curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); if($type == 'post'){ curl_setopt($ch,CURLOPT_POST,1); curl_setopt($ch,CURLOPT_POSTFIELDS,$arr); } //3.采集 $output = curl_exec($ch); //4.关闭 curl_close($ch); if($res == 'json'){ if(curl_error($ch)){ //请求失败,返回错误信息 return curl_error($ch); }else{ return json_decode($output,true); } } //var_dump($output); } //获取access_token和微信服务器ip地址 /*function getWxAccessToken(){ //1.请求url地址 $appid = 'wxd3a57f24b4e021b2'; $appsecret = 'feffb8659a14792c9323fdf27b4b35f7'; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret; //2.初始化 $ch = curl_init(); //3.设置参数 curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); //4.调用接口(采集) $res = curl_exec($ch); //5.关闭curl curl_close($ch); if(curl_errno($ch)){ var_dump(curl_error($ch)); } $arr = json_decode($res,true); var_dump($arr); }*/ //获取微信服务器ip function getWxServerIp(){ $accessToken = "9E_hA1sd77bpRQ0GqhyU4G5zpLxKZM3Yrxa1za0yyYQpWJmXif5AI3nRNUBe6xESQtQR5SbHHTkvYx5XkcnXkcXn6gVpGVGGbCswbLMMtqEfD1mGXHobq3nKtUkwFXvVSLXgABAFYK"; $url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=".$accessToken; $ch = curl_init(); curl_setopt($ch,CURLOPT_URL,$url); curl_setopt($ch,CURLOPT_RETURNTRANSFER,1); $res = curl_exec($ch); curl_close($ch); if(curl_errno($ch)){ var_dump(curl_error($ch)); } $arr = json_decode($res,true); echo "<pre>"; var_dump($arr); echo "<pre>"; } //测试实例化Model模型路径问题 public function a(){ $weChatModel = new HomeModelWeChatModel; var_dump($weChatModel); } //返回access_token; access_token存入session避免重复调用 public function getWxAccessToken(){ //将access_token 存在session/cookie中 if($_SESSION['access_token'] && $_SESSION['expires_time']>time()){ //如果access_token在session并没有过期 return $_SESSION['access_token']; }else{ //如果access_token在session不存在或者已经过期,重新取access_token $appid = 'wxd3a';//此处用你自己的appid $appsecret = 'feffb8659a14792c9323fdf';//用你自己的appsecret $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$appid."&secret=".$appsecret; $res = $this->http_curl($url,'get','json'); $access_token = $res['access_token']; //将重新获取到的access_token存入session $_SESSION['access_token'] = $access_token; $_SESSION['expires_time'] = time() + 7200; return $access_token; } } //自定义菜单 public function definedItem(){ //创建微信菜单 //目前微信接口的调用方式都是通过curl post/get header('content-type:text/html;charset=utf-8');//解决中文乱码 echo $access_token = $this->getWxAccessToken(); $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$access_token; $postArr = array( 'button'=>array( array( 'name'=>urlencode('子钦'), 'type'=>'click', 'key'=>'item1', ),//第一个一级菜单 array( 'name'=>urlencode('子钦语录'), 'sub_button'=>array( array( 'name'=>urlencode('歌曲'), 'type'=>'click', 'key'=>'songs', ),//第一个二级菜单 array( 'name'=>urlencode('私募风云网'), 'type'=>'view', 'url'=>'http://wap.simufengyun.com', ),//第二个二级菜单 ), ),//第二个一级菜单 array( 'name' =>urlencode('子钦心语'), 'type' =>'view', 'url' => 'http://wap.simufengyun.com', ),//第三个一级菜单 ), ); //其他按钮类型 $postArr2 = array( 'button'=>array( array( 'name'=>urlencode('扫码'), 'sub_button'=>array( array( 'type'=>"scancode_waitmsg", 'name'=>urlencode("扫码带提示"), 'key'=>"rselfmenu_0_0", ),//第一个二级菜单 array( 'type'=>"scancode_push", 'name'=>urlencode("扫码推事件"), 'key'=>"rselfmenu_0_1", ),//第二个二级菜单 ), ),//第一个一级菜单 array( 'name'=>urlencode("发图"), 'sub_button'=>array( array( 'type'=>'pic_sysphoto', 'name'=>urlencode("系统拍照发图"), 'key'=>"rselfmenu_1_0", ),//第一个二级菜单 array( 'type'=>'pic_photo_or_album', 'name'=>urlencode("拍照或者相册发图"), 'key'=>"rselfmenu_1_1", ),//第二个二级菜单 array( 'type'=>'pic_weixin', 'name'=>urlencode("微信相册发图"), 'key'=>"rselfmenu_1_2", ),//第三个二级菜单 ), ),//第二个一级菜单 array( 'name'=>urlencode("发送位置"), 'type'=>"location_select", "key"=>"rselfmenu_2_0", ),//第三个一级菜单 ), ); /*echo '<hr />'; var_dump($postArr); echo '<hr />'; echo $postJson = urldecode(json_encode($postArr)); $res = $this->http_curl($url,'post','json',$postJson); echo "<hr/>"; var_dump($res);*/ echo '<hr />'; var_dump($postArr2); echo '<hr />'; echo $postJson = urldecode(json_encode($postArr2)); $res = $this->http_curl($url,'post','json',$postJson); echo "<hr/>"; var_dump($res); }
    }

    Model类

    <?php
    namespace HomeModel;
    use ThinkModel;
    class WeChatModel extends Model{
        //多图文的回复微信方法
        public function responseNews($postObj,$arr)
        {
            $toUser   = $postObj->FromUserName;
            $fromUser = $postObj->ToUserName;
            $time     = time();
            $template = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <ArticleCount>".count($arr)."</ArticleCount>
                        <Articles>";
            foreach($arr as $k=>$v){
                $template .="<item>
                            <Title><![CDATA[".$v['title']."]]></Title> 
                            <Description><![CDATA[".$v['description']."]]></Description>
                            <PicUrl><![CDATA[".$v['picUrl']."]]></PicUrl>
                            <Url><![CDATA[".$v['url']."]]></Url>
                            </item>";
                }
            $template .= "</Articles>
                        </xml>";
            echo sprintf($template,$toUser,$fromUser,$time,'news');
         }
         
         //回复单文本
         public function responseText($postObj,$content){
            $template = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        </xml>";
            $toUser   = $postObj->FromUserName;
            $fromUser = $postObj->ToUserName;
            $time     = time();
            $msgType  = 'text';
            echo sprintf($template,$toUser,$fromUser,$time,$msgType,$content);
         }
        //回复用户关注消息
        public function responseSubscribe($postObj,$arr){
            $this->responseNews($postObj,$arr);
        }
     }

    7位验证的函数方法

    //生成随机数,length长度 
    function getsRandChar($length){
        $str = null;
        $strPol = "0123456789abcdefghijklmnopqrstuvwxyz";//不区分大小写
       //$strPol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";//区分大小写
    $max = strlen($strPol)-1; for($i=0;$i<$length;$i++){ $str.=$strPol[rand(0,$max)];//rand($min,$max)生成介于min和max两个数之间的一个随机整数 } return $str; }

    有不明白的加微信咨询zmd1047773569

  • 相关阅读:
    .net学习笔记----WebConfig常用配置节点介绍
    .net学习笔记----会话状态Session
    .net学习笔记---HttpRuntime类
    最优化基础(三)
    最优化基础(二)
    最优化基础(一)
    非精确线搜索
    精确线搜索——抛物线法
    Matlab自定义函数的几种方法
    精确线搜索-黄金分割法
  • 原文地址:https://www.cnblogs.com/zmdComeOn/p/9884030.html
Copyright © 2020-2023  润新知