在微信公众平台开发中,通过PHP使用数组定义微信菜单是最常用的实现方式,这种方式结构清晰,方便后续维护和调整菜单内容。正确的数组格式是成功创建菜单的基础,不符合规范的数组会导致接口调用失败。

微信菜单数组的基础结构
微信菜单分为一级菜单和二级菜单,一级菜单最多支持3个,每个一级菜单下最多支持5个二级菜单。菜单数组的最外层是一个包含button键的数组,button的值就是一级菜单的数组集合。
一级菜单字段说明
每个一级菜单元素需要包含以下基础字段:
- name:菜单名称,最多支持4个汉字或者8个英文字符
- sub_button:二级菜单数组,若没有二级菜单则不需要该字段,可直接配置菜单类型相关字段
- type:菜单类型,常见的类型有
click、view、miniprogram等
二级菜单字段说明
每个二级菜单元素需要包含的字段根据type的不同有所区别,通用基础字段如下:
- name:二级菜单名称,最多支持7个汉字或者14个英文字符
- type:菜单类型,必填
常见的菜单类型及对应数组格式
click类型菜单
click类型菜单点击后会触发微信服务器推送对应的事件,需要配置key字段,用于标识菜单的唯一标识,数组格式如下:
<?php
// click类型一级菜单,无二级菜单
$menu_1 = array(
'name' => '今日推荐',
'type' => 'click',
'key' => 'TODAY_RECOMMEND'
);
// click类型二级菜单
$sub_menu_1 = array(
'name' => '热门文章',
'type' => 'click',
'key' => 'HOT_ARTICLE'
);
?>
view类型菜单
view类型菜单点击后会直接跳转到配置的网址,需要配置url字段,数组格式如下:
<?php
// view类型二级菜单
$sub_menu_2 = array(
'name' => '官方站点',
'type' => 'view',
'url' => 'https://ipipp.com/wechat-index'
);
?>
小程序类型菜单
小程序类型菜单点击后会跳转到对应的小程序,需要配置appid、pagepath、url三个字段,数组格式如下:
<?php
// 小程序类型二级菜单
$sub_menu_3 = array(
'name' => '配套小程序',
'type' => 'miniprogram',
'url' => 'https://ipipp.com/miniprogram-entry',
'appid' => 'wxxxxxxxxxxxxxxxxxxx',
'pagepath' => 'pages/index/index'
);
?>
完整的菜单数组示例
下面是一个包含2个一级菜单,其中一个一级菜单带2个二级菜单的完整数组示例:
<?php
$menu_array = array(
'button' => array(
// 第一个一级菜单,带2个二级菜单
array(
'name' => '功能服务',
'sub_button' => array(
array(
'name' => '在线客服',
'type' => 'click',
'key' => 'ONLINE_SERVICE'
),
array(
'name' => '意见反馈',
'type' => 'view',
'url' => 'https://ipipp.com/feedback'
)
)
),
// 第二个一级菜单,无二级菜单
array(
'name' => '关于我们',
'type' => 'view',
'url' => 'https://ipipp.com/about'
)
)
);
?>
数组转JSON及接口调用
微信菜单创建接口要求传入的参数是JSON格式,并且需要是UTF-8编码,所以在PHP中需要将数组转换为JSON字符串,转换时需要注意不要进行Unicode转义,否则中文会显示为Unicode编码导致接口报错。
<?php
// 将菜单数组转换为JSON,JSON_UNESCAPED_UNICODE避免中文转义
$menu_json = json_encode($menu_array, JSON_UNESCAPED_UNICODE);
// 微信菜单创建接口地址,需要替换access_token为实际的凭证
$api_url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=YOUR_ACCESS_TOKEN';
// 使用curl发送POST请求
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $api_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $menu_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json; charset=utf-8'));
$response = curl_exec($ch);
curl_close($ch);
// 处理返回结果
$result = json_decode($response, true);
if ($result['errcode'] == 0) {
echo '菜单创建成功';
} else {
echo '菜单创建失败,错误码:' . $result['errcode'] . ',错误信息:' . $result['errmsg'];
}
?>
常见格式错误及解决方法
| 错误场景 | 错误原因 | 解决方法 |
|---|---|---|
| 接口返回40001错误 | access_token无效或者过期 | 重新获取有效的access_token,注意access_token的有效期为2小时 |
| 菜单名称显示乱码 | JSON编码时中文被转义,或者编码不是UTF-8 | 使用json_encode时添加JSON_UNESCAPED_UNICODE参数,确保PHP文件编码为UTF-8 |
| 二级菜单不显示 | 一级菜单下sub_button格式错误,或者二级菜单数量超过5个 | 检查sub_button是否为数组格式,控制二级菜单数量不超过5个 |
| 菜单类型不生效 | 对应类型的必填字段缺失,比如view类型没有url字段 | 根据菜单类型补充对应的必填字段,检查字段拼写是否正确 |
注意事项
在定义菜单数组时,还需要注意以下规则:
- 菜单名称不能包含特殊字符,仅支持中文、英文字母、数字和下划线
- 如果一级菜单有二级菜单,那么该一级菜单不需要配置type字段,type字段只需要配置在二级菜单中
- 修改菜单后,微信客户端需要重新关注或者清除缓存才能看到最新的菜单效果
- 测试号创建的菜单和正式号的菜单互不干扰,测试时可以使用测试号验证数组格式是否正确