前几天由于公司要开发微信公众平台,打开公众号开发平台官网,咋一看官方文档,竟然没得一个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()
        {
            // ..
        }




    }
?>