#### 1. 前言 ---- 為了滿足用戶渠道推廣分析和用戶帳號(hào)綁定等場(chǎng)景的需要,公眾平臺(tái)提供了生成帶參數(shù)二維碼的接口 生成帶參數(shù)的二維碼官方文檔: [https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html](https://developers.weixin.qq.com/doc/offiaccount/Account_Management/Generating_a_Parametric_QR_Code.html) 目前有兩種類型的二維碼: 1、臨時(shí)二維碼 2、永久二維碼 **應(yīng)用場(chǎng)景:** 在一個(gè)公眾號(hào)網(wǎng)頁(yè)項(xiàng)目中每個(gè)用戶都有一個(gè)邀請(qǐng)好友的海報(bào)圖片,海報(bào)圖片中有一張公眾號(hào)二維碼,掃碼二維碼即可關(guān)注公眾號(hào),通過(guò)二維碼關(guān)注公眾號(hào)的新用戶將自動(dòng)綁定為二維碼所屬用戶的下級(jí) **功能實(shí)現(xiàn):** 第一步: 給用戶都生成一個(gè)二維碼,該二維碼的場(chǎng)景值為該用戶的唯一標(biāo)識(shí),例如:`id` 第二步: 監(jiān)聽(tīng)公眾號(hào)關(guān)注事件推送,當(dāng)有用戶關(guān)注時(shí)判斷有沒(méi)有場(chǎng)景值,是不是新用戶,當(dāng)有場(chǎng)景值并且是新用戶時(shí),將該用戶綁定為場(chǎng)景值所屬用戶的下級(jí) #### 2. 代碼實(shí)現(xiàn) ---- `我在 TP6.0中 使用 EasyWechat4.x 寫(xiě)的` **一、創(chuàng)建二維碼 ticket** 場(chǎng)景值 ```php $scene = 1; // 用戶id ``` 臨時(shí)二維碼 ```php $result = $app->qrcode->temporary($scene, 6 * 24 * 3600); ``` 永久二維碼 ```php $result = $app->qrcode->forever($scene); ``` 獲取成功時(shí) $result 值示例 注: 當(dāng)公眾號(hào)appid或開(kāi)發(fā)者密鑰配置錯(cuò)誤時(shí),創(chuàng)建二維碼 ticket 將拋出異常 `expire_seconds` ticket 有效時(shí)間, 也就是二維碼的有效時(shí)間,獲取臨時(shí)二維碼ticket時(shí)才有該字段 ``` ^ array:3 [▼ "ticket" => "gQG37zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxxx" "expire_seconds" => 518400 "url" => "http://weixin.qq.com/q/027J3KsSeoc4E1B0h61x1k" ] ``` **二、使用二維碼 ticket,生成二維碼** ```php // 獲取二維碼網(wǎng)址(返回二維碼圖片地址) $url = $app->qrcode->url($result['ticket']); ``` $url 示例值如下所示: (其實(shí)就是 `https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=` 拼接上 `ticket值`) ``` https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=gQG37zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyN0ozS3NTZW9jNEUxQjBoNjF4MWsAAgRAaH5hAwQA6QcA ``` 獲取二維碼完整示例 ``` $config = [ 'app_id' => "wx0a48233ca8xxxx", 'secret' => "2674bb2165dc7c45160cxxx", 'response_type' => 'array', // 指定API調(diào)用返回結(jié)果的類型 ]; $app = \EasyWeChat\Factory::officialAccount($config); try { // 場(chǎng)景值 $scene = 1; // 創(chuàng)建二維碼ticket, 當(dāng)公眾號(hào)appid或開(kāi)發(fā)者密鑰配置錯(cuò)誤時(shí)將拋出異常 $result = $app->qrcode->temporary($scene, 6 * 24 * 3600); if (isset($result['errcode']) && $result['errcode'] == 48001) { // 48001: 個(gè)人訂閱號(hào)沒(méi)有權(quán)限調(diào)用高級(jí)接口 // api unauthorized rid: 615f013d-15fcf84b-054f4b9b fault($result['errmsg']); } } catch (\Exception $e) { fault($e->getMessage()); } // 獲取二維碼網(wǎng)址(返回二維碼圖片地址) $url = $app->qrcode->url($result['ticket']); echo "<img src=" . $url . ">"; ``` **三、關(guān)注公眾號(hào),綁定上下級(jí)關(guān)系** 用戶關(guān)注公眾號(hào)后,微信服務(wù)器會(huì)向 `服務(wù)器配置URL` 推送一個(gè)消息,并攜帶一下數(shù)據(jù)包格式 服務(wù)器URL配置參考官方文檔,本文不做介紹: [https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html](https://developers.weixin.qq.com/doc/offiaccount/Basic_Information/Access_Overview.html) ```php array ( 'ToUserName' => 'gh_cff380f5a988', 'FromUserName' => 'ozlgE6DGcfpHE1Qz69U9xKQtsRkw', 'CreateTime' => '1635671639', 'MsgType' => 'event', 'Event' => 'subscribe', 'EventKey' => 'qrscene_1', 'Ticket' => 'gQGG7zwAAAAAAAAAAS5odHRwOi8vd2VpeGluLnFxLmNvbS9xLzAyMkhpbHREZW9jNEUxQjc3Nk54YzgAAgRHXn5hAwQA6QcA', ) ``` 分析下數(shù)據(jù)包中的數(shù)據(jù),直 `FromUserName` 為用戶在該公眾號(hào)下的openid | 字段 | 描述 | | ------------ | ------------ | | FromUserName | 用戶在該公眾號(hào)下的openid | | MsgType | 消息類型,event 代表是當(dāng)前消息是事件推送 | | Event | 值為subscribe代表時(shí)關(guān)注事件推送 | | EventKey | qrscene_ 是固定前綴,1 是生成二維碼時(shí)傳入的場(chǎng)景值 | $message 假設(shè)是上面的消息數(shù)據(jù)包,下面是關(guān)注公眾號(hào)后的邏輯處理示例 ```php // 判斷是否是關(guān)注事件 if (!empty($message['Event']) && !empty($message['EventKey']) && $message['Event'] == 'subscribe') { // 匹配場(chǎng)景值 preg_match('/_(\d+)$/', $message['EventKey'], $match); if (!empty($match[1])) { // 場(chǎng)景值 $scene = $match[1]; // 判斷當(dāng)前用戶是不是新用戶,是新用戶則進(jìn)行上下級(jí)關(guān)系綁定 // ... } } ```