一、说明

1、根据慕课网上的教程为基础,这是前两个基础教程:
PHP实现微信公众平台开发—基础篇:https://www.imooc.com/video/9316
PHP实现微信公众平台开发—提升篇 :https://www.imooc.com/video/10231
2、慕课上视频讲解用的是thinkphp早期版本,我用的是thinkphp3.2.3版本。可以看慕课视频进行学习,讲的比较详细
PHP微信公众平台开发高级篇—自定义菜单:https://www.imooc.com/video/11332
3、代码亲测有效

二、IndexController控制器代码

<?php
namespace Weixin\Controller;
use Think\Controller;

class IndexController extends Controller{
    public function __construct(){
    
    }//可以不写
    public function index(){
        //获得参数 signature nonce token timestamp echostr
        $nonce     = $_GET['nonce'];
        $token     = 'weixin';
        $timestamp = $_GET['timestamp'];
        $echostr   = $_GET['echostr'];
        $signature = $_GET['signature'];
        //形成数组,然后按字典序排序
        $array = array();
        $array = array($nonce, $timestamp, $token);
        sort($array);
        //拼接成字符串,sha1加密 ,然后与signature进行校验
        $str = sha1( implode( $array ) );
        if( $str  == $signature && $echostr ){
            //第一次接入weixin api接口的时候
            echo  $echostr;
            exit;
        }else{
            $this->definedItem();
            $this->reponseMsg();
        }
    }
    // 接收事件推送并回复
    public function reponseMsg(){
        //1.获取到微信推送过来post数据(xml格式)
        //$postArr = $GLOBALS['HTTP_RAW_POST_DATA'];//php7开始不支持
        $postArr = file_get_contents("php://input"); 
        //2.处理消息类型,并设置回复类型和内容
        $postObj = simplexml_load_string( $postArr );
        
        //判断该数据包是否是订阅的事件推送
        if( strtolower( $postObj->MsgType) == 'event'){
            //如果是关注 subscribe 事件
            if( strtolower($postObj->Event == 'subscribe') ){
                /* //回复用户消息(纯文本格式)    
                $toUser   = $postObj->FromUserName;
                $fromUser = $postObj->ToUserName;
                $time     = time();
                $msgType  =  'text';
                //$content  = '欢迎关注我们的微信公众账号'.$postObj->FromUserName.'-'.$postObj->ToUserName;
                $content  = '欢迎关注放哥的微信公众账号';
                $template = "<xml>
                            <ToUserName><![CDATA[%s]]></ToUserName>
                            <FromUserName><![CDATA[%s]]></FromUserName>
                            <CreateTime>%s</CreateTime>
                            <MsgType><![CDATA[%s]]></MsgType>
                            <Content><![CDATA[%s]]></Content>
                            </xml>";
                $info = sprintf($template, $toUser, $fromUser, $time, $msgType, $content);
                echo $info; */ 
                //回复一个单图文
                $arr = array(
                    array(
                        'title'=>'程序员的天堂',
                        'description'=>"欢迎来到放哥的公众号",
                        'picUrl'=>'http://www.imooc.com/static/img/common/logo.png',
                        'url'=>'http://www.imooc.com',
                    ),
                );
                $model = new \Weixin\Model\IndexModel();
                $model -> responseSubscribe($postObj, $arr);
            }
        }
         //dump($postObj->Event); 
         //dump($postObj->Eventkey);
        //自定义菜单中event->click事件
         if( strtolower($postObj->Event) == 'click'){
             $key = (string)$postObj->EventKey;
            if(strtolower($key == 'item1')){
                $content = "这是item1菜单的事件推送";
            }elseif(strtolower($key == 'songs')){
                $content = "这是歌曲菜单的事件推送";
            } else {
                $content = '未匹配'.print_r($postObj->EventKey, true);
            }
            $model = new \Weixin\Model\IndexModel();
            $model -> responseText($postObj, $content);
        }
        
        //如果是自定义菜单中的event->view
        if(strtolower($postObj->Event) == 'view'){
            $content="跳转的链接是".$postObj->EventKey;
            $model = new \Weixin\Model\IndexModel();
            $model -> responseText($postObj, $content);
        }    
        
        //用户发送tuwen1关键字的时候,回复一个单图文
        if( strtolower($postObj->MsgType) == 'text' && trim($postObj->Content)=='tuwen2' ){
            //从数据库中查询得到
            $arr = array(
                array(
                    'title'=>'imooc',
                    'description'=>"imooc is very cool",
                    'picUrl'=>'http://www.imooc.com/static/img/common/logo.png',
                    'url'=>'http://www.imooc.com',
                ),
                array(
                    'title'=>'hao123',
                    'description'=>"hao123 is very cool",
                    'picUrl'=>'https://www.baidu.com/img/bdlogo.png',
                    'url'=>'http://www.hao123.com',
                ),
                array(
                    'title'=>'qq',
                    'description'=>"qq is very cool",
                    'picUrl'=>'http://www.imooc.com/static/img/common/logo.png',
                    'url'=>'http://www.qq.com',
                ),
            );
            //实例化模型
            $model = new \Weixin\Model\IndexModel();
            $model -> responseNews($postObj, $arr);

            //注意:进行多图文发送时,子图文个数不能超过10个
        }else{
            switch(trim($postObj->Content)){
                case 1:
                    $content = '您输入的数字是1';
                break;
                case 2:
                    $content = '您输入的数字是2';
                break;
                case 3:
                    $content = '您输入的数字是3';
                break;
                case 4:
                    $content = "<a href='http://www.imooc.com'>慕课</a>";
                break;
                case '英文':
                    $content = 'imooc is ok';
                break;
                default:
                    $content = '没有找到相关信息';
            }    
            //实例化模型
            $model = new \Weixin\Model\IndexModel();
            $model -> responseText($postObj, $content);
        }//if end
    }//reponseMsg end

/*     function http_curl(){
        //获取imooc
        //1.初始化curl
        $ch = curl_init();
        $url = 'http://www.baidu.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
    */
    public function http_curl($url,$type='get',$res='json',$arr=''){
        //1.初始化curl
        $ch = curl_init();
        //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);
            }
        }
    }

    /* function getWxAccessToken(){
        //1.请求url地址
        $appid = 'wxb20bebb764546087';
        $appsecret =  '64e22d215895d52af21c8fcbf6da3241';
        $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 );
    } */

    function getWxServerIp(){
        $accessToken = "10_GeE-KKSKq5PE_K3gLKJE7bmAJKJS2hh0qwM5ZwTSJaGtY6DJ3o5moOvT0TjpScimSG4g4LfjShJc6unkfKThjAcdinCJsWyS0RIIdWJLnJ_yBN3Qa06DTf63ZgkC86N7lmfRNcsVuwdthW35AXIdABAKHS";
        $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>";
    }
    /*
    *返回access_token *session解决办法 存mysql memcache
    */
    public function getWxAccessToken(){
        //将access_token 存在session/cookie中
        if($_SESSION['access_token'] && $_SESSION['expire_time'] > time()){
            //如果access_token在session中没有过期
            return $_SESSION['access_token'];
        }else{
            //如果access_token在session中不存在或者已经过期
            $appid = 'wxb20bebb764546087';
            $appsecret = '64e22d215895d52af21c8fcbf6da3241';
            $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['erpire_time'] = time() + 7000;
            return $access_token;
        }
    }
    /* 创建微信菜单
    目前微信接口的调用方式都是curl post/get */
    public function definedItem(){
        header('content-type:text/html;charset=utf-8');
        echo $access_token = $this->getWxAccessToken();
        echo '<br />';
        $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://www.baidu.com',
                            ),//第二个二级菜单
                        ),
                    ),//第二个一级菜单
                    array(
                        'name' => urlencode('菜单三'),
                        'type' => 'view',
                        'url' => 'http://www.qq.com',
                    ),//第三个一级菜单
                ),
            );
        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);
    }
}//class end

三、IndexModel模型代码

<?php
namespace Weixin\Model;

class IndexModel{
    //回复多图文类型的微信消息
    public function responseNews($postObj ,$arr){
        $toUser = $postObj->FromUserName;
        $fromUser = $postObj->ToUserName;
        $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>";
        //注意模板中的中括号 不能少 也不能多
        $fromUser = $postObj->ToUserName;
        $toUser   = $postObj->FromUserName; 
        $time     = time();
        $msgType  = 'text';
        echo sprintf($template, $toUser, $fromUser, $time, $msgType, $content);
    }

    //回复微信用户的关注事件
    public function responseSubscribe($postObj, $arr){
        $this->responseNews($postObj,$arr);
    }
}

本文由 一切随风 创作,可自由转载、引用,但需署名作者且注明文章出处。

8 条评论

  1. pbirbrymqf
    pbirbrymqf

    做了几十年的项目 我总结了最好的一个盘(纯干货)

  2. geuwylttnv
    geuwylttnv

    猫步2回归的猫

  3. ozwxyfudes
    ozwxyfudes

    女巫复仇

  4. poqlaqzldm
    poqlaqzldm

    银河护卫队3

  5. akhdwxitxc
    akhdwxitxc

    走出非洲

  6. tvqsmeywkl
    tvqsmeywkl

    诺拉

  7. xmiqykesgu
    xmiqykesgu

    无限旅程

  8. fmfzeichns
    fmfzeichns

    十年一品温如言

添加新评论