1. 程式人生 > 實用技巧 >最全面 think php 實現微信公眾號回覆編號進行投票,自定義選單功能

最全面 think php 實現微信公眾號回覆編號進行投票,自定義選單功能

前期準備工作

https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html 微信文件

公眾號後臺,“基本配置”-“伺服器配置”,填寫伺服器地址,注意,填寫的方法要經過驗證

test方法只是測試,具體的要看你自己的方法,其中$token就是後臺填寫的“令牌”,驗證通過後,所有在公眾號傳送的資訊,都會轉發到所填的連結上,注意:開啟伺服器配置後,公眾號的自定義選單會失效,公眾號的自定義選單會消失

    public
function test(){ $nonce = $_GET['nonce']; $token = '*******'; $timestamp = $_GET['timestamp']; $echostr = $_GET['echostr']; $signature = $_GET['signature']; //形成陣列,然後按字典序排序 $array = array(); $array = array($nonce, $timestamp, $token); sort($array);
//拼接成字串,sha1加密 ,然後與signature進行校驗 $str = sha1( implode( $array ) ); echo $echostr; exit; }
$file_in = file_get_contents("php://input"); //接收post資料
//用SimpleXML解析POST過來的XML資料
$postObj = simplexml_load_string($file_in,'SimpleXMLElement',LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName; //獲取傳送方帳號(OpenID)
$toUsername = $postObj->ToUserName; //獲取接收方賬號
$keyword = trim($postObj->Content); //獲取訊息內容
$masType = $postObj->MsgType;//獲取訊息型別,可以作分類判斷。本例預設是文字訊息,不做判斷
$time = time(); //獲取當前時間戳








//---------- 返 回 數 據 ---------- //
//返回訊息模板
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";

$msgType = "text"; //訊息型別
if($masType != 'text'){
$contentStr = "回覆內容*****";
}else if(trim($keyword) == ''){
$contentStr = "傳送不能為空";
}else if(is_numeric($keyword)){
if(!is_numeric($keyword)||strpos($keyword,".")!==false){
$contentStr = "編號不正確,請查詢後再進行投票";
$resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);
echo $resultStr;
return;
}
$data1['toupiao_time'] = date("Y-m-d");

$message = M('message_cun');

$b = $message->where("member_id = '%s' and ip = '%s' and toupiao_time = '%s'",$keyword,$fromUsername,$data1['toupiao_time'])->count();
if($b > 0 ){
$contentStr = "您已對該項投票,請明天再來!";
$resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);
echo $resultStr;
return;
}
$a = $message->where("ip = '%s' and toupiao_time = '%s'",$fromUsername,$data1['toupiao_time'])->count();
if ($a >= 10) {
$contentStr = "您已投滿10票,請明天再來!";
$resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);
echo $resultStr;
return;
}else{
$data['member_id'] = $keyword;
$data['ip'] =(string) $fromUsername;
$data['userName'] = (string) $toUsername;
$data['toupiao_time'] = date("Y-m-d");
$res = $message->data($data)->add();
if($res){
$contentStr = "投票成功";
$resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);
echo $resultStr;
}
}
}else{
$contentStr = "******回覆內容";
}
$resultStr = sprintf($textTpl,$fromUsername,$toUsername,$time,$msgType,$contentStr);
echo $resultStr;

可以看到,在接受到資訊後,獲取編號,往記錄表中插入一條資料,有兩個表,記錄表(記錄插入的所有票數),投票表(記錄要投票的主體,票數),重點:建立一個觸發器,在記錄表插入時,根據 編號,使投票表中編號對應的票數+1

member_id 就是從微信獲取的編號,member_cun就是投票表,code就是投票表中的編號,這樣是就實現了微信回覆編號,進行投票。

自定義選單:

開啟伺服器配置後,之前自定義的選單就沒了,就需要我們通過介面自定義了。

https://developers.weixin.qq.com/doc/offiaccount/Message_Management/Receiving_standard_messages.html 微信文件,

在建立之前,我們可以查詢一下http請求方式: GET(請使用https協議)https://api.weixin.qq.com/cgi-bin/get_current_selfmenu_info?access_token=ACCESS_TOKEN,查詢出當前公眾號的選單,建立的時候就不用挨個想之前建立的是啥了,

建立時要注意格式,其他的沒有什麼特別注意的點,注意傳送的json格式一定要對,post請求,可以使用除錯工具除錯你自己的json格式,

下面是一個可以進行 post請求的方法,

呼叫如下,其中 $data2 就是json格式的字串

$res = $this->http("https://api.weixin.qq.com/cgi-bin/menu/create?access_token=".$access_token,"POST",$data2);

    public function http($url, $method, $postfields = null, $headers = array(), $debug = false)
    {
        $ci = curl_init();
        /* Curl settings */
        curl_setopt($ci, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 30);
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, FALSE);
        curl_setopt($ci, CURLOPT_TIMEOUT, 30);
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);

        switch ($method) {
            case 'POST':
                curl_setopt($ci, CURLOPT_POST, true);
                if (!empty($postfields)) {
                    curl_setopt($ci, CURLOPT_POSTFIELDS, $postfields);
                    $this->postdata = $postfields;
                }
                break;
        }
        curl_setopt($ci, CURLOPT_URL, $url);
        curl_setopt($ci, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($ci, CURLINFO_HEADER_OUT, true);

        $response = curl_exec($ci);
        $http_code = curl_getinfo($ci, CURLINFO_HTTP_CODE);

        if ($debug) {
            echo "=====post data======\r\n";
            var_dump($postfields);

            echo '=====info=====' . "\r\n";
            print_r(curl_getinfo($ci));

            echo '=====$response=====' . "\r\n";
            print_r($response);
        }
        curl_close($ci);
//        return array($http_code, $response);
        return  $response;
    }

附上一個json格式,各個引數的意思可以在微信文件中檢視,可以放連結,小程式

{
    "button": [
        {
            "name": "***", 
            "sub_button": [
                {
                    "type": "view", 
                    "name": "***", 
                    "url": "https://www.baidu.com/"
                } 
            ]
        }, 
        {
            "name": "***", 
            "sub_button": [
                {
                    "type": "miniprogram", 
                    "name": "小程式", 
                    "url": "****", 
                    "appid": "", 
                    "pagepath": ""
                }
            ]
        }
    ]
}

其中介面中需要的access_token,需要你通過微信的appid和開發者密碼來獲取,注意一個過期時間,一天可以訪問2000次,access_token的有效期目前為2個小時,需定時重新整理,重複獲取將導致上次獲取的access_token失效,好的做法是建立一個表存token,

判斷最後一次獲取的時間和當前時間的差,超過多長時間重新獲取存庫

需要注意的是,ip白名單要新增上,只有新增的ip才可以獲取token,還有“公眾號設定”-“功能設定”,授權域名要新增,新增的方法都有提示,下載一個txt文件到網站根目錄,然後驗證就可以了,一遍不行多試幾遍,

如果真的因為失誤token次數超了,影響業務, 可以在微信後臺清空請求次數,再次請求,token一定要存庫,不能每次用到都請求新的,不然很容易就超過限制。

  $access_time = M("weixin_cun")->order("id desc")->getField("time");
        $time = time() - strtotime($access_time);
        if($time>2000){
            $url="https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=".$this->app_id."&secret=".$this->app_secret;
            $content = file_get_contents($url);
            $result = json_decode($content);
            $data['access_token'] = $result->access_token;
            if(!empty($data['access_token'])){
                $weixin = M("weixin_cun")->data($data)->add();
            }else{

            }
        }

至此,實現微信公眾號回覆編號進行投票,自定義選單功能 完成。