您现在的位置是:网站首页 > 心得笔记
微信公众号开发——自定义菜单
1、自定义菜单注意点:
自定义菜单最多包含3个一级菜单,每个一级菜单最多包含5个二级菜单。
一级菜单最多展示4个汉字,二级菜单最多展示7个汉字,多出来的部分将会以...代替。
修改自定义菜单后由于缓存原因(24小时),可能不能立刻显示出来。测试时可以尝试取消关注公众号再次关注,则可以看到修改后的效果。
2、自定义菜单——按钮类型click和view
click:点击推事件 用户点击click类型按钮后,key会随着事件推传递到第三方开发的url上。微信服务器会通过消息接口推送消息类型为event的结构给开发者(参考消息接口指南),并且带上按钮中开发者填写的key值,开发者可以通过自定义的key值与用户进行交互;
view :跳转url用户点击view类型按钮后,微信客户端将会打开开发者在按钮中填写的网页URL,可与网页授权获取用户基本信息接口结合,获得用户基本信息。
3、创建自定义菜单
官方链接https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421141013
3.1、申请微信提供的测试账号
创建接口基于我们认证后的服务号(非订阅号,订阅号满足不了我们这里的需求)。我这里并不是使用真正的服务号,而是基于微信自己提供的测试账号,测试账号功能跟微信认证的服务号相比较,大部分能满足。
开发者工具->公众平台测试账号 申请测试账号(注意:这里申请的是一个新的账号,不同于之前订阅号,所以appid appsecret都不一样了),配置测试账号信息,我还是按照之前订阅号配置的
3.2、代码实现自定义菜单
<?php namespace App\Http\Controllers\Front; use App\Http\Controllers\Controller; use App\Model\Admin\Test; use Illuminate\Http\Request; class TestController extends Controller { public function api() { $echoStr = isset($_GET["echostr"]) ? $_GET["echostr"] : ''; if (!empty($echoStr) && $this->checkSignature()) { echo $echoStr; exit; } else { $postStr = file_get_contents("php://input", 'r'); //写入日志 在同级目录下建立php_log.txt error_log(var_export($postStr,1),3,'php_log.txt'); if (!empty($postStr)){ libxml_disable_entity_loader(true); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); //自定义菜单的事件推送 if (strtolower($postObj->Event) == 'click') { if (strtolower($postObj->EventKey) == 'item1') { $content = '这是item1菜单的事件推送'; } if (strtolower($postObj->EventKey) == 'songs') { $content = '这是歌曲菜单的事件推送'; } $test->responseText($postObj,$content); } //如果自定义菜单中的event->view if (strtolower($postObj->Event) == 'view') { $content = '跳转链接是'.$postObj->EventKey; $test->responseText($postObj, $content); } } else { echo ""; exit; } } } //检查签名 private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = "weixin"; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if($tmpStr == $signature){ return true; }else{ return false; } } /** * $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_setopt($ch, CURLOPT_URL, $url);//设置url curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);//将抓取的数据返回 if ($type == 'post') { curl_setopt($ch, CURLOPT_POST, 1);//定义是post请求 curl_setopt($ch, CURLOPT_POSTFIELDS, $arr);//$arr是从第三方传过来的json 也可能是 数组 } //3、调用接口 $output = curl_exec( $ch ); //4、关闭curl if ($res == 'json') { if (curl_errno( $ch )) {//请求失败,返回错误信息 return curl_error( $ch ); } else {//请求成功,json结果转为数组 return json_decode($output, true); } } curl_close($ch); } //获取access_token 存储在session中 并返回 public function getWxAccessToken () { if (!empty(session('access_token')) && session('expire_time') > time()) {//如果session中存在access_token并且过期时间大于当前时间 return session('access_token'); } else { $appid = 'wx9886cbdb96107XXX'; $appsecret = 'cf51fd33152723d3408420fea54faXXX'; $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(['expire_time'=> time() + 7200]); return $access_token; } } //创建微信菜单 public function definedItem () { //设置header头 可使乱码消失 header('content-type:text/html;charset=utf-8'); //目前微信接口的调用方式都是curl post/get $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://www.baidu.com', ),//第二个二级菜单 ), ),//第二个一级菜单 array( 'name' => urlencode('菜单三'), 'type' => 'view', 'url' => 'http://www.qq.com', ),//第三个一级菜单 ), ); $postJson = urldecode(json_encode($postArr));//中文在json中展示变成其他字符 $res = $this->http_curl($url, 'post', 'json', $postJson); } }
Test.php模型
<?php namespace App\Model\Admin; use Illuminate\Database\Eloquent\Model; class Test extends Model { //回复单文本的微信消息 public function responseText ($postObj, $content) { $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $time = time(); $template = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> </xml>"; $msgType = "text"; $resultStr = sprintf($template, $fromUsername, $toUsername, $time, $msgType, $content); echo $resultStr; } }
演示效果图:
4、自定义菜单中的事件推送
自定义菜单时间推送有两种形式:
click:单击时 发送事件推送到我们第三方开发者填写的url地址上
view:当我们菜单是url地址跳转时,它也会推送事件到我们填写的第三方开发者的url地址上
具体代码已经写在上面了!参考之~~~
此例有坑:
问题1:你在编写时可能会遇到问题Protocol https not supported or disabled in libcurl
解决方法:网址url前面有一个空格,去掉就正常了
问题2:中文乱码问题
解决方法:在中文处,使用urlencode(),将字符串以URL编码,用于编码处理;再设置header头 可使乱码消失 header('content-type:text/html;charset=utf-8');
上一篇:第三方天气查询接口在微信中的使用
下一篇:微信公众号开发——群发接口