程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> 關於PHP編程 >> 微信訂閱號開發之token驗證後,自動回復消息功能做好,發送消息沒有返回,token自動回復

微信訂閱號開發之token驗證後,自動回復消息功能做好,發送消息沒有返回,token自動回復

編輯:關於PHP編程

微信訂閱號開發之token驗證後,自動回復消息功能做好,發送消息沒有返回,token自動回復


相信很多人會跟我一樣,token驗證之後,發送消息給訂閱號,沒有消息返回。

以下,說一下我辛苦調試得到的解決辦法:

首先,token驗證:

自己寫的token一直驗證失敗,找了好久,沒有發現bug。實在沒辦法,就用了官方的示例代碼。並且通過示例代碼調試,發現了一個讓我吐血的bug(也不算bug):

token驗證貌似要求字符編碼格式!!!!

官方的示例代碼,直接上傳到服務器,token直接過!

把官方示例代碼改為UTF-8格式,再上傳覆蓋,token失敗失敗!失敗!

後來,把自己寫的修改為ANSI格式還是token失敗!醉了醉了!那只好用官方示例代碼。在此,說下,token是一次握手驗證,驗證過一次就不用了。

 

下面,言歸正傳,貌似偏題了...orz

token驗證之後,直接用官方示例代碼,趕緊測試自己的訂閱號,結果....發出去的消息就跟潑出去的水一樣,什麼鬼都沒有返回...orz

又各種找bug,各種群問,各種搜索....歷經本博主九九八十一的努力,終於找出了問題所在(這裡是指我自己開發的,並不包括全部,如果你有不同的bug,歡迎交流):

1、最容易被忽視的一個bug,官方給的示例代碼,壓根就沒調用寫好的那個responseMsg()函數!

2、把之前的token代碼注釋,也就是$wechatObj->valid();這行代碼。因為toke驗證那段代碼會有一個echo $echostr,會把responseMsg()函數裡的echo $resultStr;(56行)xml格式混亂,輸回給微信服務器就無法識別了(貌似只能識別xml格式,還有json格式)。(token驗證是一次握手驗證,驗證開發者之後,就可以不用了,趕緊讓它消失在我們整潔的代碼orz...)

3、最惡心的一個bug,還是字符編碼問題!orz...xml要求UTF-8編碼,所以,把示例代碼改回UTF-8編碼!這個bug找的讓我崩潰!!!

 

下面是我修改後的代碼,能正常運行,無bug,需要的可以參考一下

 1 <?php
 2 /**
 3   * wechat php test
 4   */
 5 
 6 //define your token
 7 define("TOKEN", "codcodog");
 8 
 9 $wechatObj = new wechatCallbackapiTest();
10 //$wechatObj->valid();
11 $wechatObj->responseMsg();
12 
13 class wechatCallbackapiTest
14 {
15     public function valid()
16     {
17         $echoStr = $_GET["echostr"];
18 
19         //valid signature , option
20         if($this->checkSignature()){
21         header('content-type:text');
22             echo $echoStr;
23             exit;
24         }
25     }
26 
27     public function responseMsg()
28     {
29         //get post data, May be due to the different environments
30         $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
31         //$postStr = file_get_contents("php://input");
32         file_put_contents("log.txt",$postStr,FILE_APPEND );
33           //extract post data
34         if (!empty($postStr)){
35                 /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
36                    the best way is to check the validity of xml by yourself */
37                 libxml_disable_entity_loader(true);
38                   $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
39                 $fromUsername = $postObj->FromUserName; //用戶
40                 $toUsername = $postObj->ToUserName;     //公眾平台
41                 $keyword = trim($postObj->Content);
42                 $time = time();
43                 $textTpl = "<xml>
44                             <ToUserName><![CDATA[%s]]></ToUserName>
45                             <FromUserName><![CDATA[%s]]></FromUserName>
46                             <CreateTime>%s</CreateTime>
47                             <MsgType><![CDATA[%s]]></MsgType>
48                             <Content><![CDATA[%s]]></Content>
49                             <FuncFlag>0</FuncFlag>
50                             </xml>";             
51                 if(!empty( $keyword ))
52                 {
53                       $msgType = "text";
54                     $contentStr = "Welcome to wechat world!";
55                     $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
56                     echo $resultStr;
57                 }else{
58                     echo "Input something...";
59                 }
60 
61         }else {
62             echo "";
63             exit;
64         }
65     }
66         
67     private function checkSignature()
68     {
69         // you must define TOKEN by yourself
70         if (!defined("TOKEN")) {
71             throw new Exception('TOKEN is not defined!');
72         }
73         
74         $signature = $_GET["signature"];
75         $timestamp = $_GET["timestamp"];
76         $nonce = $_GET["nonce"];
77                 
78         $token = TOKEN;
79         $tmpArr = array($token, $timestamp, $nonce);
80         // use SORT_STRING rule
81         sort($tmpArr, SORT_STRING);
82         $tmpStr = implode( $tmpArr );
83         $tmpStr = sha1( $tmpStr );
84         
85         if( $tmpStr == $signature ){
86             return true;
87         }else{
88             return false;
89         }
90     }
91 }
92 
93 
94 ?>

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved