摘要: 这个demo包含了获取token,绑定微信号,设置自定义菜单,响应文本和事件
这个教程的基础篇和提升篇都看完了,总感觉有点隔靴挠痒的感觉,讲的东西我都懂,没有吸收多少新鲜的知识。貌似还没有我这个一年前写的脚本好呢,估计也是照顾新人吧。期待高级篇的讲解,不过现在高级篇估计还在录制当中,所以对微信公众平台开发的学习就先到这里吧。
下面介绍一下我很久以前写的这个脚本。基本上常用的几个功能都有了,access_token的获取,用户的微信号和公司的账号的绑定,查询公司服务器上的数据,自定义表单什么。不过随着水平的提高,现在返回头来看,确实有很多的不足,比较最明显的就是token获取之后,没有保存下载,而是每一次访问都会获取一次,这个问题可以把token放入memcache中来解决。把代码贴上:
<?php //获取ACCESS_TOKEN $appid = "xxxxxxxxxxxxxxxxxxxxx"; $appsecret = "xxxxxxxxxxxxxxxxxxxxxxxxxxxx"; $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appid}&secret={$appsecret}"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); $output = curl_exec($ch); curl_close($ch); $jsoninfo = json_decode($output, true); $access_token = $jsoninfo["access_token"]; //获取ACCESS_TOKEN end //define my token define("TOKEN", "xxxxxxxxxx"); //define my ACCESS_TOKEN define("ACCESS_TOKEN",$access_token); class IndexAction extends Action { public function index(){ $this->responseMsg(); $this->createMenu(); } public function valid() { $echoStr = $_GET["echostr"]; //valid signature , option if($this->checkSignature()){ echo $echoStr; exit; } } /* description of 文本展示 @param none @return none @author act @vision */ public function responseMsg() { //获取微信发来的数据 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //extract post data if (!empty($postStr)){ //将这个xml编程一个对象 $postObj = simplexml_load_string($postStr, ‘SimpleXMLElement‘, LIBXML_NOCDATA); $openid=$postObj->FromUserName; $openid=(string)$openid; $text_type = trim($postObj->MsgType); //获取消息类型 switch ($text_type) { case ‘text‘: $content=trim($postObj->Content); //功能:绑定用户 //微信号,公司账号内容绑定,格式: 用户名+手机号+身份证后四位 $user_info=explode(‘+‘,$content); $username=$user_info[0]; //用户提交的用户名 $phone=$user_info[1]; //提交的手机号码 $card_id=$user_info[2]; //提交的电话号码 $user_info_count=count($user_info); if( $user_info_count==3){ //如果数组的元素为三个,说明就是验证微信号 $model=new Model(); $sql="select a.user_id,a.username,b.phone,c.card_id from deayou_users as a left join deayou_users_info as b on a.user_id=b.user_id left join deayou_approve_realname as c on a.user_id=c.user_id where a.username=‘{$username}‘ and b.phone=‘{$phone}‘ and right(c.card_id,4)=‘{$card_id}‘"; $res=$model->query($sql); $cond[‘openid‘]=$openid; $is_openid=M(‘weixin_user_bind‘)->where($cond)->find(); //是否已经绑定过 if($res && $is_openid){ //此刻 说明是修改 /* 以下注释的代码不要删除,万一哪天还要改回来,删掉注释即可。 */ // $where1[‘openid‘]=array(‘eq‘,$openid); // $where[‘users_table_id‘]=$res[0][‘user_id‘]; // $res=M(‘weixin_user_bind‘)->where($where1)->data($where)->save(); // if($res){ // $resultStr=$this->responseText($postObj,‘恭喜您,修改绑定成功‘); // }else{ // $resultStr=$this->responseText($postObj,‘修改绑定失败,请检查用户名、手机号、身份证号码是否一致‘); // } $resultStr=$this->responseText($postObj,‘您已经绑定过账号了,请不要再次绑定‘); }elseif ($res && empty($is_openid)) { //此刻说明是添加 $cond[‘users_table_id‘]=$res[0][‘user_id‘]; $cond[‘openid‘]=$openid; $result=M(‘weixin_user_bind‘)->where($cond)->add($cond); if($result){ $resultStr=$this->responseText($postObj,‘恭喜您,账号绑定成功‘); }else{ $resultStr=$this->responseText($postObj,‘账号绑定失败,请检查用户名、手机号、身份证号码是否一致‘); } }else{ $resultStr=$this->responseText($postObj,‘请输入正确格式,并且请检查用户名、手机号、身份证号码是否一致‘); } }else{ $resultStr=$this->responseText($postObj,‘您好,感谢您关注xxx官方微信服务号!‘); } break; case ‘event‘: $cond[‘openid‘]=$openid; $res=M(‘weixin_user_bind‘)->where($cond)->find(); if($res){ $_SESSION[‘user_id‘]=$res[‘users_table_id‘]; } $resultStr = $this->handleEvent($postObj); default: # code... break; } echo $resultStr; }else { echo ""; exit; } } /* description of 文本调用 @param $Obj 用户传入数据对象 @return 一个返回给用户的xml字符串 @author act @vision */ public function handleText($obj){ $postObj = $obj; $toUsername = $postObj->ToUserName; $fromUsername = $postObj->FromUserName; $keyword = trim($postObj->Content); $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>"; if(!empty($keyword)){ $MsgType=‘text‘; $Content=‘欢迎加入xxx‘; $resultStr=sprintf($textTpl,$fromUsername,$toUsername,$time,$MsgType,$Content); return $resultStr; } } /* description of 事件调用 @param $Obj 用户传入数据对象 @return 一个返回给用户的xml字符串 @author act @vision */ public function handleEvent($obj){ $content=‘‘; /** * 判断账户是否已经绑定 */ $openid=$obj->FromUserName; $openid=(string)$openid; $data[‘openid‘]=$openid; $is_bind=M(‘weixin_user_bind‘)->where($data)->select(); switch (strtolower($obj->Event)) { case ‘subscribe‘: $content="您好,感谢您关注xxx官方微信服务号!"; break; case ‘click‘: $key=$obj->EventKey; switch($key){ //switch 判断出key值 依次判断 case ‘zhbd‘: if($is_bind){ $content = ‘您已经绑定过账户了哦~‘; }else{ $content = ‘请输入验证信息‘."\n".‘格式(加号也要写上哦~):‘."\n"."用户名+手机号+身份证后4位"."\n"."例如:"."\n"."iloveyou+13800000000+1111"; } break; case ‘xxzh‘: if(empty($_SESSION[‘user_id‘])){ $resultStr=$this->responseText($obj,‘请先进行账号绑定‘); return $resultStr; } $content = R(‘Info/select_account‘); break; case ‘jrxyb‘: if(empty($_SESSION[‘user_id‘])){ $resultStr=$this->responseText($obj,‘请先进行账号绑定‘); return $resultStr; } $content = R(‘Info/select_xinyibao‘); break; case ‘sbxx‘: if(empty($_SESSION[‘user_id‘])){ $resultStr=$this->responseText($obj,‘请先进行账号绑定‘); return $resultStr; } $content = R(‘Info/select_sanbiao‘); break; case ‘jkxx‘: if(empty($_SESSION[‘user_id‘])){ $resultStr=$this->responseText($obj,‘请先进行账号绑定‘); return $resultStr; } $content = R(‘Info/select_jiekuan‘); break; default: $content = ‘即将推出,敬请期待^_^‘; break; } break; default: $content=‘不知道这个‘.$obj->Event; break; } $resultStr=$this->responseText($obj,$content); return $resultStr; } /* description of 返回文本 @param $Obj 用户传入数据对象 @param $cont 返回给用户的内容 @param $flag 不太了解(貌似没有多大作用) @return 一个返回给用户的xml字符串 @author act @vision */ public function responseText($Obj,$cont,$flag=0){ $postObj = $Obj; $toUsername = $postObj->ToUserName; $fromUsername = $postObj->FromUserName; $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‘; $resultStr=sprintf($textTpl,$fromUsername,$toUsername,$time,$MsgType,$cont); return $resultStr; } /* description of 系统验证 不用管 @param none @return none @author I don‘t know @vision none */ 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; } } /* description of 自定义菜单 @param $data 传入自定义菜单的json数组 @return post提交执行结果 @author act @vision */ function createMenu($data){ $data = ‘{ "button":[ { "name":"业务咨询", "sub_button":[ { "type":"view", "name":"我要理财", "url":"http://www.baidu.com" }, { "type":"view", "name":"我要贷款", "url":"http://www.baidu.com" }, { "type":"view", "name":"我要加盟", "url":"http://www.baidu.com" }, { "type":"view", "name":"我要建议", "url":"http://www.baidu.com" } ] }, { "name":"xxx在线", "sub_button":[ { "type":"click", "name":"账户绑定", "key":"zhbd" }, { "type":"click", "name":"查询账户", "key":"xxzh" }, { "type":"click", "name":"加入xxx", "key":"jrxyb" }, { "type":"click", "name":"散投信息", "key":"sbxx" }, { "type":"click", "name":"借款信息", "key":"jkxx" }] }, { "name":"关于我们", "sub_button":[ { "type":"view", "name":"公司简介", "url":"http://www.baidu.com" }, { "type":"view", "name":"安全保障", "url":"http://www.baidu.com" }, { "type":"view", "name":"联系我们", "url":"http://www.baidu.com" }] }] }‘; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".ACCESS_TOKEN); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($ch, CURLOPT_USERAGENT, ‘Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)‘); curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); curl_setopt($ch, CURLOPT_AUTOREFERER, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $tmpInfo = curl_exec($ch); if (curl_errno($ch)) { return curl_error($ch); } curl_close($ch); return $tmpInfo; } }