您现在的位置是:网站首页 > 心得笔记
微信公众号开发——自定义菜单
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');
上一篇:第三方天气查询接口在微信中的使用
下一篇:微信公众号开发——群发接口