在微信公众号开发中,若要通过代码设置自定义菜单并关联图文消息,需要先获取永久图文素材的media_id
(而非直接获取文章的数据库ID)。以下是完整实现流程:
一、获取图文消息 media_id
的步骤
1. 上传图文素材到微信服务器
// 微信公众号配置
define('APPID', 'your_appid');
define('APPSECRET', 'your_appsecret');
// 获取 access_token
function getAccessToken() {
$url = "https://api--qq-com/cgi-bin/token?grant_type=client_credential&appid=".APPID."&secret=".APPSECRET;
$res = json_decode(file_get_contents($url), true);
return $res['access_token'];
}
// 上传图文素材
function uploadNews($access_token, $articles) {
$url = "https://api-weixin-qq-com/cgi-bin/material/add_news?access_token={$access_token}";
$post_data = [
"articles" => $articles
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data, JSON_UNESCAPED_UNICODE));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// 使用示例
try {
$access_token = getAccessToken();
$articles = [
[
"title" => "文章标题",
"thumb_media_id" => "封面图片的media_id", // 需先上传图片素材
"author" => "作者",
"digest" => "摘要",
"show_cover_pic" => 1,
"content" => "文章内容(支持HTML)",
"content_source_url" => "原文链接"
]
];
$result = uploadNews($access_token, $articles);
if(isset($result['media_id'])) {
echo "素材上传成功!media_id: " . $result['media_id'];
} else {
echo "上传失败:" . json_encode($result);
}
} catch(Exception $e) {
echo "错误:" . $e->getMessage();
}
2. 获取已上传的素材列表(可选)
function getMaterialList($access_token, $type='news', $offset=0, $count=20) {
$url = "https://api--qq-com/cgi-bin/material/batchget_material?access_token={$access_token}";
$post_data = [
"type" => $type,
"offset" => $offset,
"count" => $count
];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($post_data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// 使用示例
$list = getMaterialList($access_token);
print_r($list); // 返回结果中包含 media_id 列表
二、创建带图文消息的菜单
1. 创建菜单代码(使用 media_id
类型)
function createMenu($access_token) {
$url = "https://api--qq-com/cgi-bin/menu/create?access_token={$access_token}";
$menu = [
"button" => [
[
"type" => "media_id",
"name" => "最新文章",
"media_id" => "你的图文素材media_id" // 这里填写上一步获取的media_id
],
[
"name" => "更多内容",
"sub_button" => [
[
"type" => "view_limited",
"name" => "历史文章",
"media_id" => "另一个media_id"
]
]
]
]
];
// ...(发送请求的代码同前文创建菜单示例)
}
三、关键区别说明
参数 | 用途 |
| 永久素材的唯一标识,用于菜单中直接发送图文消息 ( |
| 用于修改已发布的图文消息(通过 |
四、注意事项
- 素材类型限制:
media_id
类型菜单:用户点击直接发送图文消息view_limited
类型菜单:跳转到图文消息页面
- 素材有效期:
- 永久素材无过期时间,但每月有上传限额(默认5000个)
- 常见错误码:
40007
: 无效的media_id → 检查素材是否被删除40001
: 无效的access_token → 重新获取token
- 调试建议:
- 使用微信官方调试工具
- 先通过
getMaterialList
接口确认素材是否存在
通过上述代码,您可以实现通过PHP代码管理微信菜单与图文消息的关联。如果需要动态更新菜单内容,可以结合数据库存储media_id
实现灵活配置。