微信服務號支援自定義選單(最多 3 個一級選單,每個最多 5 個二級選單)。開發過程中常因 JSON 格式錯誤導致建立失敗。本文提供一個封裝完整的 weixinMenu 類,涵蓋 access_token 獲取、選單建立/查詢/刪除、HTTP GET/POST 通用方法,可直接整合至專案。
<?php
/**
* 微信自定義選單管理類
* @author LSH
*/
class weixinMenu {
// 配置常數(請填入實際值)
public static $appid = 'YOUR_APPID';
public static $secret = 'YOUR_SECRET';
// 微信 API 端點
public static $getToken = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential';
public static $createMenu = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=';
public static $selMenu = 'https://api.weixin.qq.com/cgi-bin/menu/get?access_token=';
public static $delMenu = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=';
// cURL 通用選項
public static $opt = array(
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_USERAGENT => 'Mozilla/5.0 (compatible; MSIE 5.01; Windows NT 5.0)',
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_AUTOREFERER => 1,
CURLOPT_RETURNTRANSFER => true
);
public $ACCESS_TOKEN = null;
/** 建立選單 */
public function create() {
$this->token();
$strMenu = '{
"button": [
{ "type": "click", "name": "選單左", "key": "V_MENU_LEFT" },
{ "type": "click", "name": "選單中", "key": "V_MENU_CENTER" },
{ "type": "click", "name": "選單右", "key": "V_MENU_RIGHT" }
]
}';
$ret = $this->HttpPost(self::$createMenu . $this->ACCESS_TOKEN, self::$opt, $strMenu);
echo $ret;
}
/** 查詢選單 */
public function sel() {
$this->token();
$ret = $this->HttpGet(self::$selMenu . $this->ACCESS_TOKEN, self::$opt);
echo $ret;
}
/** 刪除選單 */
public function del() {
$this->token();
$ret = $this->HttpGet(self::$delMenu . $this->ACCESS_TOKEN, self::$opt);
echo $ret;
}
/** 獲取 access_token(建議加入快取機制) */
private function token() {
$tokenUrl = self::$getToken . "&appid=" . self::$appid . "&secret=" . self::$secret;
$ret = $this->HttpGet($tokenUrl, self::$opt);
$arrRet = json_decode($ret, true);
$this->ACCESS_TOKEN = $arrRet['access_token'];
}
/** POST 請求 */
private function HttpPost($url, $opt = array(), $post_data) {
$setopt = array(
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url,
CURLOPT_CUSTOMREQUEST => 'POST',
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $post_data
);
if (!empty($opt)) {
foreach ($opt as $key => $value) { $setopt[$key] = $value; }
}
$curl = curl_init($url);
foreach ($setopt as $key => $value) { curl_setopt($curl, $key, $value); }
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
/** GET 請求 */
private function HttpGet($url, $opt = array()) {
$setopt = array(
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_URL => $url
);
if (!empty($opt)) {
foreach ($opt as $key => $value) { $setopt[$key] = $value; }
}
$curl = curl_init($url);
foreach ($setopt as $key => $value) { curl_setopt($curl, $key, $value); }
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
}
?>
<?php require_once 'weixinMenu.php'; $menu = new weixinMenu(); // 建立選單 $menu->create(); // 查詢當前選單 // $menu->sel(); // 刪除選單 // $menu->del(); ?>
json_encode() 產生 JSON 字串,避免手寫錯誤。click:點擊推事件(需配合事件回覆邏輯)。view:跳轉網頁(需配置網頁授權域名)。scancode_push、scancode_waitmsg:掃碼推事件/等待回覆。pic_sysphoto、pic_photo_or_album、pic_weixin:拍照/相册發圖。location_select:發送地理位置。CURLOPT_SSL_VERIFYPEER,生產環境建議下載微信 CA 憑證並啟用驗證。private function buildMenuArray() {
return [
'button' => [
['type' => 'click', 'name' => '首頁', 'key' => 'HOME'],
['type' => 'view', 'name' => '關於我們', 'url' => 'https://example.com/about'],
[
'name' => '服務',
'sub_button' => [
['type' => 'click', 'name' => '線上客服', 'key' => 'SERVICE_ONLINE'],
['type' => 'view', 'name' => '常見問題', 'url' => 'https://example.com/faq'],
]
]
]
];
}
// 建立時:
$menuJson = json_encode($this->buildMenuArray(), JSON_UNESCAPED_UNICODE);
$ret = $this->HttpPost(self::$createMenu . $this->ACCESS_TOKEN, self::$opt, $menuJson);
weixinMenu 類封裝了微信自定義選單的全生命週期操作,核心在於正確組裝 JSON 結構與access_token 管理。實際專案中建議加入快取層、錯誤重試、日誌記錄,並將選單結構存放於資料庫/配置檔,實現可視化管理。