微信公众平台开发案例

前几天由于公司要开发微信公众平台,打开公众号开发平台官网,咋一看官方文档,竟然没得一个demo,弄了半天才明白是咋个回事,看起来容易但又感觉不好下手;网上这方面的代码案例比较少,而且都是凌乱的几个方法,新手很难接受,

现在把我们公众平台开发的完整代码贴出来给大家参考一下,让新手少走点弯路,文章最后有我对整个代码总结的中心思想;

<?php
    header("Content-type: text/html; charset=utf-8");
    define ( "TOKEN", "aidaijia" );   
    
    $wechatObj = new WeiXin();

    class WeiXin{
        private static $ACCESS_TOKEN = 0;  //当前access_token的值
        private static $ACCESS_TIME = 0;  //access_token最后一次更新的时间
        private static $XMLDATA;  //接收请求的xml数据
        private static $ARRELE = array();  //存放请求的xml节点 用来判断是属于那种请求
        public function __construct()
        {
            // $this->valid();die;   //服务器验证
            // $this->createMenu();die;   //自定义菜单
            $path = dirname(__FILE__);
            $acpath = $path."/weixin.c";  //存放最近一次access_token更新的时间
            $access = $path."/access_token.c";  //最近一次更新的access_token
            $xml = $path."/xmldata.c";   //存放最近一次接收的xml数据
            
            //检查access_token是否过期
            if(!file_exists($acpath)){        
                $this->getAssessToken();
                file_put_contents($acpath, self::$ACCESS_TIME);
                file_put_contents($access, self::$ACCESS_TOKEN);        
            }else
            {
                $acint = file_get_contents($acpath)+0;
                if((time()-$acint)>=7000)
                {
                    $this->getAssessToken();
                    file_put_contents($acpath, self::$ACCESS_TIME);
                    file_put_contents($access, self::$ACCESS_TOKEN);
                }else
                {
                    self::$ACCESS_TOKEN = file_get_contents($access);
                }
            }
            //校验信息真实性(防止微信以外的第三方灌水机器人)
            $this->checkSignature();
            //将请求的xml数据存为全局
            self::$XMLDATA = $GLOBALS["HTTP_RAW_POST_DATA"];
            //添加xml数据日志
            file_put_contents($xml, self::$XMLDATA);

            $this->begin();
        }
        

        private function begin()
        {

            $postObj = simplexml_load_string(self::$XMLDATA, 'SimpleXMLElement', LIBXML_NOCDATA);
            foreach ($postObj as $key => $value) {
                array_push(self::$ARRELE,$key);
            }
            
            //事件消息
            if(in_array("Event", self::$ARRELE))
            {    
                //新用户关注
                if($postObj->Event=="subscribe")
                {
                    $textTpl = "
                    <xml>
                    <ToUserName><![CDATA[".$postObj->FromUserName."]]></ToUserName>
                    <FromUserName><![CDATA[".$postObj->ToUserName."]]></FromUserName>
                    <CreateTime>".time()."</CreateTime>
                    <MsgType><![CDATA[news]]></MsgType>
                    <ArticleCount>2</ArticleCount>
                    <Articles>
                    <item>
                    <Title><![CDATA[爱代驾送福利:百万代驾券、iPhone6大奖等你来拿!]]></Title>
                    <Description><![CDATA[爱代驾送福利]]></Description>
                    <PicUrl><![CDATA[http://aidaijia.com/Public/Index/image/tu1.jpg]]></PicUrl>
                    <Url><![CDATA[http://aidaijia.com/home]]></Url>
                    </item>
                    <item>
                    <Title><![CDATA[酒后有车咋个走,爱代驾只需29]]></Title>
                    <Description><![CDATA[爱代驾最低29元起]]></Description>
                    <PicUrl><![CDATA[http://aidaijia.com/Public/Index/image/syx4.jpg]]></PicUrl>
                    <Url><![CDATA[http://aidaijia.com/Index/Index/price]]></Url>
                    </item>
                    </Articles>
                    </xml>";  
                    echo $textTpl;
                    return ;
                }
                //取消关注
                if($postObj->Event=="unsubscribe")
                {
                    $sql = "delete from dj_weixin where wuser='$postObj->FromUserName'";
                    $mysqli = new mysqli("localhost", "username", "666666", "driver");
                    $mysqli->query($sql);
                    $mysqli->close();
                    return ;
                }

                //更新用户的坐标
                if($postObj->Event=='LOCATION')
                {
                    //上报地理位置事件
                    if(in_array("Latitude",self::$ARRELE) )
                    {
                        $time = time();
                        $obj = simplexml_load_string(self::$XMLDATA, 'SimpleXMLElement', LIBXML_NOCDATA);
                        $sql = "insert into `dj_weixin` (`wuser`, `wlon`, `wlat`, `wtime`,`wto`) values ('$obj->FromUserName', $obj->Longitude, $obj->Latitude, $time,'$obj->ToUserName') ON DUPLICATE KEY UPDATE `wlon` = $obj->Longitude, `wlat` = $obj->Latitude, `wtime` =$time, `wto` ='$obj->ToUserName' ;";
                        // $access = dirname(__FILE__)."/access_token.c";
                        // file_put_contents($access, $sql);
                        $mysqli = new mysqli("localhost", "username", "666666", "driver");
                        $mysqli->query($sql);
                        $mysqli->close();
                        return;
                    }
                }
                
            }
            //用户主动发送了位置信息
            if(in_array("Location_X",self::$ARRELE))
            {
                self::fdriver();
                return;
            }
            //自定义菜单事件
            if(in_array("EventKey",self::$ARRELE))
            {

                if(substr($postObj->EventKey,0,3)=='WD_')
                {
                    self::menuevent();
                    return ;
                }
            }
            //普通消息
            if($postObj->MsgType=='text')
            {
                self::responseMsg();
                return;
            }
        }

        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;
            }
        }
        
        
        //获取access_token
        public function getAssessToken(){
            $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=wxfa50fcdbae10f8c8&secret=e845e613792e369034a91b9bd2db513a ";
            $curl = curl_init($url);
            curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);  //以文件流的形式返回
            $data = curl_exec($curl);
            $arr = json_decode($data, true); //把返回的json字符串转化为数组
            self::$ACCESS_TOKEN = $arr['access_token'];  //更新access_token
            self::$ACCESS_TIME = time();  //最后一次获取access_token的时间
            curl_close($curl);
            // echo self::$ACCESS_TOKEN."<br>";
            // echo self::$ACCESS_TIME."<br>";
        }

    

        //回复文本消息
        public function responseMsg()
        {
              $postObj = simplexml_load_string(self::$XMLDATA, 'SimpleXMLElement', LIBXML_NOCDATA);
            $fromUsername = $postObj->FromUserName;
            $toUsername = $postObj->ToUserName;
            $content = $postObj->Content;
            $contentStr = "";
            if(substr($content,0,1)=='@')
            {
                $pos = substr($content,1);
                if(strlen($pos)!=11)
                {
                    $contentStr = "温馨提示:请填写正确的手机号";
                }else
                {
                    $path = dirname(__FILE__);
                    $xmlele = $path."/xmlele.c";
                    $sql = "select * from dj_order_info where from_phonenum='$pos' order by orderid desc limit 4";
                    $mysqli = new mysqli("localhost", "username", "666666", "driver");
                    $result = $mysqli->query($sql);
                    $mysqli->close();
                    while($obj = $result->fetch_object()){
                        $contentStr.="单号".$obj->order_num."\n------->时间".substr($obj->call_time,5,5)."\n";
                    }
                    if($contentStr=='')
                        $contentStr = "你好,没有查询到相关订单";
                }
            }
            $time = time();
            $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>0</FuncFlag>
                        </xml>";             
              $msgType = "text";
              if($contentStr=='')
                $contentStr = "你好,我是爱代驾,你可以在这里快速找代驾,近期订单查询,进入微官网还有更多惊喜,24小时客服热线:4000700029
            爱代驾是一家历史悠久的代驾公司,公司本着以人为本,诚信经营的宗旨,在全国享有很高的声誉
            ";
            $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
            echo $resultStr;
        }
        // 自定义菜单事件消息
        public static function menuevent()
        {
            $obj = simplexml_load_string(self::$XMLDATA, 'SimpleXMLElement', LIBXML_NOCDATA);
            $eventKey = $obj->EventKey;
            $fromUsername = $obj->FromUserName;
            $toUsername = $postObj->ToUserName;
            $time = time();
            $msgType = "text";
            $content = $eventKey;
            switch($eventKey)
            {
                case "WD_JIAGE":
                    $content = "7:00-21:00=>29元起\n21:00-24:00=>49元起\n0:00-7:00=>69元起\n"; break;
                case "WD_ZHAODAIJIA":
                    self::finddriver($fromUsername);break;
                    // $content = "请发送你的位置以便寻找附近司机:\n1、点击左下方 '小键盘' \n2、点击右下方 '+号键' \n3、点击 '位置' 图标\n4、完成定位后点击 '发送'"; break;
                case "WD_DINGDAN":
                    $content = "请发送@+手机号查询"; break;
                case "WD_FUWUREXIAN":
                    $content = "24小时服务热线:4000-7000-29"; break;
                default:
                    // $content = "无法识别";
            }
            $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[%s]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>0</FuncFlag>
                        </xml>";
            $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $content);
            echo $resultStr;                    
        }
        //寻找附近司机,针对于开启了位置服务的用户,我方公众号需要在公众平台开启高级权限接口并启用位置服务
        public static function finddriver($username)
        {
            // $access = dirname(__FILE__)."/access_token.c";
            
            $sql = "select * from dj_weixin where wuser = '$username'";
            $mysqli = new mysqli("localhost", "username", "666666", "driver");
            $res = $mysqli->query($sql);
            $mysqli->close();
            $count = 0;
            if($res->num_rows!=0)
            {
                $obj = $res->fetch_object();
                $lon = $obj->wlon;
                $lat = $obj->wlat;
                $fromUsername = $obj->wuser;
                $toUsername = $obj->wto;
                $time = $obj->wtime;
                $nowtime = time();
                if(($nowtime-$time)>120)
                {
                    $count=-1;
                    goto flag;
                }
                
            }else
            {
                $obj = simplexml_load_string(self::$XMLDATA, 'SimpleXMLElement', LIBXML_NOCDATA);
                $fromUsername = $obj->FromUserName;
                $toUsername = $obj->ToUserName;
                $count = -1;
                goto flag;
            }
            $sql = "call queryDriverByClient($lat,$lon)";
            $mysqli = new mysqli("localhost", "username", "66666666", "driver");
            $result = $mysqli->query($sql);
            $mysqli->close();
            $count = $result->num_rows;
            //如果没有获取到用户的地理信息 直接跳到这里
            flag :
            $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>0</FuncFlag>
                        </xml>";
            if($count>0)
            {
                $content = "你附近有".$count."个空闲司机。\n马上去选司机: http://aidaijia.com/find?lat=".$lat."&lon=".$lon;
            }
            else
            {
                if($count==-1)
                    $content = "无法获取你的地理位置,请点击爱代驾头像,在资料页面把[提供位置信息]开启\n你也可以手动发送地理位置信息:\n1、点击左下方 '小键盘' \n2、点击右下方 '+号键' \n3、点击 '位置' 图标\n4、完成定位后点击 '发送'";
                else
                    $content = "抱歉!你附近暂没有空闲司机。你可以等会儿在操作或拨打客服咨询4000-7000-29\n";
            }
            $time = time();
            $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time,     $content);
            echo $resultStr;
        }

        //寻找附近的司机  针对没有开启位置服务的用户  (需要用户手动发送位置信息)
        public static function fdriver()
        {
            $obj = simplexml_load_string(self::$XMLDATA, 'SimpleXMLElement', LIBXML_NOCDATA);
            
            $lon = $obj->Location_Y ;   //经度
            $lat = $obj->Location_X ;  //纬度
            $fromUsername = $obj->FromUserName;
            $toUsername = $obj->ToUserName;
            $sql = "call queryDriverByClient($lat,$lon)";
            $mysqli = new mysqli("localhost", "username", "666666", "driver");
            $result = $mysqli->query($sql);
            $mysqli->close();
            $count = $result->num_rows;
            $textTpl = "<xml>
                        <ToUserName><![CDATA[%s]]></ToUserName>
                        <FromUserName><![CDATA[%s]]></FromUserName>
                        <CreateTime>%s</CreateTime>
                        <MsgType><![CDATA[text]]></MsgType>
                        <Content><![CDATA[%s]]></Content>
                        <FuncFlag>0</FuncFlag>
                        </xml>";
            if($count>0)
            {
                $content = "你附近有".$count."个空闲司机。\n马上去选司机: http://aidaijia.com/find?lat=".$lat."&lon=".$lon;
            }
            else
            {
                $content = "抱歉!你附近暂没有空闲司机。你可以等会儿在操作或拨打客服咨询4000-7000-29\n";
            }
            $time = time();
            $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $content);
            echo $resultStr;
        }
        
        //设置菜单
        public function createMenu(){
            $url = "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=DWJG0l5MhgkJBDfjg032jnOfjwZX3Fatk1PccFNgJuRYr0b8I3w-jd77P2_p95pJd4xtFB_DdZRi5k-WHaSNGA";
            $btnjson =  '{
                 "button":[{    
                      "type":"click",
                      "name":"找代驾",
                      "key":"WD_ZHAODAIJIA"
                  },
                  {
                      "name":"微助手",
                       "sub_button":[
                       {
                           "type":"view",
                          "name":"微官网",
                          "url":"http://aidaijia.com/home"
                       },
                       {
                           "type":"view",
                           "name":"路况信息",
                           "url":"http://map.baidu.com/mobile/webapp/index/index/foo=bar/vt=map&traffic=on&viewmode=no_ad/?third_party=ucsearchbox#index/index/foo=bar/vt=map&traffic=on&viewmode=no_ad"
                       },
                       {
                           "type":"click",
                          "name":"最近订单",
                          "key":"WD_DINGDAN"
                       }
                       ]
                      
                  },
                  {
                       "name":"更多服务",
                       "sub_button":[
                       {
                           "type":"click",
                           "name":"服务热线",
                           "key":"WD_FUWUREXIAN"
                       },
                       {
                           "type":"click",
                           "name":"价格列表",
                           "key":"WD_JIAGE"
                       },
                       {
                           "type":"view",
                           "name":"下载客户端",
                           "url":"http://aidaijia.com/d"
                       }
                       
                   ]
                  }]
             }';
            $curl = curl_init();
            curl_setopt($curl, CURLOPT_URL, $url);
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $btnjson);
            $data = curl_exec($curl);
            curl_close($curl);
            echo $data;
        }

        //验证服务器
        public function valid()
        {
            $echoStr = $_GET["echostr"];

            //valid signature , option
            if($this->checkSignature()){
                echo $echoStr;
                exit;
            }
        }

        //收尾工作
        public function __destruct()
        {
            // ..
        }

    }
?>

总结:

在微信公众平台开启开发者模式(其实有两个模式,一个是给普通人使用的,一个是给开发者使用的,默认是普通模式),开启开发者模式后,以后关注你的用户发送任何信息或者触发任何事件给你 ,都会走开发者路线,这些所有的信息都会以xml的形式发送到你制定的网址(比如:www.hello.com/doweixin.php),所有的数据都由这个doweixin.php来处理,里面的代码就类似我上面的代码,所以我们要做的事情就是解析用户发送过来的xml数据,通过这里面的数据 我们就可以知道用户想要什么 触发了我们定义的某个按钮
,那么我们根据业务返回用户所需要的数据  我们返回的数据也是xml形式  ,我上面的代码都是被动触发,也就是用户主动来给你发送消息或者触发了某个事件,对于一些营销的任务微信也提供了给你的关注用户主动推送消息的接口 但是有使用次数限制   一般就几次  ,其实这篇文章已经写好了很久了  只是感觉还有要写的  但又没时间  所以一直放在草稿箱 今天打开偶然看到了   感觉也没什么要添加的   就这样草草的发了  如果有朋友对代码有疑问就直接在下面留言吧

时间: 2024-11-04 22:25:25

微信公众平台开发案例的相关文章

微信公众平台开发问答

微信公众平台开发问答是一个微信知识问答区,专注于提供微信应用及开发技术知识的整理.归类和检索. 主题:新手常见问题 问:我是新手,没有开发基础,应该如何学习微信公众平台的开发?答:先学习PHP和Mysql,可以在网上找相应的教程,也可参考书籍<PHP和MySQL Web开发(原书第4版)>:再学习微信公众平台开发入门教程,了解微信收发消息原理及回复:然后根据微信开发文档,熟悉接口,并在此基础上实现一些基本的小功能,并扩展到更复杂的功能上. 问:URL和Token是什么意思?有什么用?我应该如何

微信公众平台开发(89) 高级群发接口

在这篇微信公众平台高级接口开发教程中,我们将介绍如何开发高级群发接口功能. 本文分为以下四个部分: 准备群发内容 选择群发对象 执行群发 接收群发结果 一.准备群发内容 群发内容可以是文本.图片.语音.视频.图文.群发文本只需要文本内容,其他内容需要获得相应的media_id. 1. 文本内容 文本内容就是一段文字,比如:"微信公众平台开发最佳实践" 2. 图片.语音.视频 要求如下: ? 图片(image): 128K,支持JPG格式 ? 语音(voice):256K,播放长度不超过

微信公众平台开发教程(六)获取个性二维码

微信公众平台开发教程(六)获取个性二维码 一.功能介绍 在进行推广时,我们可以告诉对方,我们的微信公众账号是什么,客户可以去搜索,然后关注.二维码给我们提供了极大的便捷,只要简单一扫描,即可关注. 如果已经关注过,立刻跳入对话画面.在我们进行推广时,不再是简陋的文字,可以是一个有个性的二维码,想必会很生动. 微信对二维码提供了很好的支持,而且还可以根据需要生成不同场景的二维码.下面我们将介绍如何获取和使用二维码. 注意:限服务号,且进行了微信认证,费用300 二.相关接口 为了满足用户渠道推广分

[转]微信公众平台开发(四) 简单回复功能开发

本文转自:http://www.cnblogs.com/mchina/p/3155072.html 一.简介 微信公众平台可以根据用户发送的信息进行判断,然后给出对应的回复,具有良好的交互性.下文将模拟简单的回复功能,根据这个案例,开发者也可以基本理解微信交互的原理,进行更深层次的开发. 二.思路分析 用户发送过来的文本信息,我们可以提取关键字,通过简单的 if...elseif...else... 实现. 关键代码如下: if($keyword=="你好"){ $contentStr

微信公众平台开发教程新手解惑40则

[编者按]由CSDN和<程序员>杂志联合主办的 2014年微信开发者大会 将于8月23日在北京举行,邀请了来自于一线的微信开发商技术负责人或资深工程师从企业应用开发高级篇.智能客服与LBS.微信支付.微信上的HTML5社交应用.微信小店开发等角度为与会者带来实战分享( 议程 ).目前报名处于优惠票价阶段,通过申请加入CSDN CTO俱乐部即可享受8折购票价格(票款中均含午餐),在8月1日前完成付款的同学还将免费获赠微信开发图书一本(两选一,活动现场发放).  值得一提的是,CSDN优秀博主.畅

PHP微信公众平台开发高级篇—微信JS-SDK

PHP微信公众平台开发高级篇—微信JS-SDK 第一步.绑定域名: 第二步.引入JS文件: 第三部.通过Config接口注入权限验证配置 第四部.通过Read接口处理成功验证 第五部.通过Error接口处理失败验证 实际案例:分享接口内容

微信公众平台开发教程(四) 实例入门:机器人(附源码)

微信公众平台开发教程(四) 实例入门:机器人(附源码) 上一篇文章,写了基本框架,可能很多人会觉得晕头转向,这里提供一个简单的例子来予以说明,希望能帮你解开谜团. 一.功能介绍 通过微信公众平台实现在线客服机器人功能.主要的功能包括:简单对话.查询天气等服务. 这里只是提供比较简单的功能,重在通过此实例来说明公众平台的具体研发过程.只是一个简单DEMO,如果需要的话可以在此基础上进行扩展. 当然后续我们还会推出比较复杂的应用实例. 二.具体实现 1.提供访问接口 这里不再赘述,参照上一章,微信公

微信公众平台开发(107) 分享到朋友圈和发送给好友

关键字:微信公众平台 JSSDK 发送给朋友 分享到朋友圈 onMenuShareTimeline onMenuShareAppMessage 作者:方倍工作室 原文:http://www.cnblogs.com/txw1958/p/weixin-js-sharetimeline.html 在这篇微信公众平台开发教程中,我们将介绍如何在网页中实现发送给朋友和分享到朋友圈时内容参数自定义的功能. 本文分为以下二个部分: 生成JS-SDK权限验证签名 实现发送给朋友和分享到朋友圈时内容参数自定义 一

微信公众平台开发(四) 简单回复功能开发

原文地址:http://www.cnblogs.com/mchina/p/3155072.html 一.简介 微信公众平台可以根据用户发送的信息进行判断,然后给出对应的回复,具有良好的交互性.下文将模拟简单的回复功能,根据这个案例,开发者也可以基本理解微信交互的原理,进行更深层次的开发. 二.思路分析 用户发送过来的文本信息,我们可以提取关键字,通过简单的 if...elseif...else... 实现. 关键代码如下: if($keyword=="你好"){ $contentStr