當初看了好長時間,微信文檔坑不少,然後忘記做筆記,只寫了代碼。現在寫一遍,給以後做筆記。先寫個開頭。
微信的坑爹文檔:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1445241432
簡單的上手,沒有註冊公衆號的話,先去開始開發->接口測試號申請,去申請一個測試號,掃個碼即可。
進去之後,會有公衆號信息給你,appID和appsecret,這些在驗證的時候都要使用,相當與自己公衆號的ID識別。
之後需要填寫URL和Token。
URL:自己接入的服務器域名,例:www.wechat.com/wechat,這樣就調用了這個路由的方法。
Token:相當於你在微信設置的一個密碼,在驗證的時候需要比較是否一樣。
PS:實際上還有一個參數,EncodingAESKey。測試號是無法填寫的,不過可以去接開始開發->接口在線調試中可以填寫來測試。
這個參數是消息的加密密匙,微信加密共有3種模式,1.明文模式 2.兼容模式 3.安全模式
1.明文模式:無加密 2.兼容模式:加密和未加密一起發送 3.安全模式:只有加密
2和3都需要填寫EncodingAESKey,加密後需要一些解密操作,現在先不管。
填寫完URL和Token後,我們可以開始寫程序。
首先,需要驗證信息是否來自微信。我們看微信文檔。
需要用到上述幾個參數,按照上面的方法寫,爲了方便直接貼代碼了。這裏以TP5爲例,可以根據自己的框架進行修改。
1.驗證參數:
//獲取參數
$token ='token';
$receive = $this->request;
$signature = $receive->get('signature');
$timestamp = $receive->get('timestamp');
$nonce = $receive->get('nonce');
//組合字符串
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpArr = sha1(implode($tmpArr));
//對比參數
return $tmpArr == $signature;
如果你用框架的話,可以用框架自己的接收方法,這邊只是提供一個例子。
2.返回echostr
驗證完後,需要我們原樣返回echostr。
$receive = $this->request;
if (!empty($receive->get('echostr'))) {
$echostr = $receive->get('echostr');
return $echostr;
}
這樣我們就能完成了驗證是否是微信發來的信息了。
3.接收用戶信息
微信文檔寫着,當普通微信用戶向公衆賬號發消息時,微信服務器將POST消息的XML數據包到開發者填寫的URL上。
查看下面的文檔,給出了一大堆可以接收的信息。文本,圖片,語音,視頻等等。微信默認發送的是XML格式的數據,我們需要先接收這XML數據,之後對XML進行解析。解析完後,才能開始寫對應的返回數據。先看下微信發送的信息,以文本信息爲例。
可以看到這邊有ToUserName接受者(我們的公衆號),FromUserName發送者 (用戶),CreateTime創建時間,MsgType信息類型Content文本內容 ,MsgId信息Id。其他的可以看微信文檔,我就不寫出來了。
這裏直接放解析的代碼:
//獲取XML
$msg = file_get_contents("php://input");
if (empty($msg)) return '';
//解析XML
libxml_disable_entity_loader(true);
$postObj = simplexml_load_string($msg, 'SimpleXMLElement', LIBXML_NOCDATA);
如果有興趣的話可以去看下這幾個方法是什麼意思。其實自己寫的話最好封裝一個類,這樣調用就行,像這樣一大堆長的代碼寫着也不美觀。
解析完代碼後我們就獲得了用戶的發送過來的信息了。
4.處理用戶信息
拿到用戶的數據後,第一件事就是識別信息的類型,分辨出用戶的信息後,我們才能採取對應的發放來返回信息。
例:
switch ($postObj->MsgType) {
case 'text':
return $this->handleText($postObj);
break;
default:
return '';
我們就對文本進行數據處理,其他都默認不處理。
現在先看文檔
我們需要返回以上數據,然後返回微信發送過來的那種格式
注意,這裏微信的坑就來了,這個返回格式,那些有空格的地方是不需要放空格的。
下面貼上代碼:
if (!empty($postObj->Content)) {
$ToUserName = $postObj->FromUserName;
$FromUserName = $postObj->ToUserName;
$CreateTime = time();
$MsgType = 'text';
$Content = '歡迎回復';
$template = "<xml><ToUserName><![CDATA[%s]]></ToUserName>\n<FromUserName><![CDATA[%s]]></FromUserName>\n<CreateTime>%s</CreateTime>\n<MsgType><![CDATA[%s]]></MsgType>\n<Content><![CDATA[%s]]></Content>\n</xml>";
$info = sprintf($template, $ToUserName, $FromUserName, $CreateTime, $MsgType, $Content);
return $info;
}
return '';
上述代碼應該容易理解,把相應的數據放進自己寫的模板裏去,和我上面說的一樣,模板格式多餘的空格不要。
最後,你只需要把上述代碼結合一下就能完成初步的開發了,之後給自己的公衆號發送下信息嘗試下吧。