最近在研究用PHP做微信開發的時候,“修改配置時”,總是遇到token驗證失敗的提示。歷經一番查詢,種種輸出日誌和echo,發現,如果不echo除錯資訊,也不寫日誌,就不需要ob_clean(),如果一旦啟用了輸出或者寫日誌檔案,那麼在最後的echo結果前,一定要呼叫ob_clean(),否則就會呼叫失敗。
經測試,以下三種情況都會遇到相同的問題。
真想知道,如果使用了輸出緩衝而不用ob_clean()清理的話,騰訊那邊接收到的東西是什麼,為什麼會導致失敗。
情況一:
<?php //$file = 'log.txt';//要寫入檔案的檔名(可以是任意檔名),如果檔案不存在,將會建立一個 //file_put_contents($file, "---開始日誌---" . PHP_EOL, FILE_APPEND); //file_put_contents($file, date('Y-m-d H:i:s',time()) . PHP_EOL, FILE_APPEND); //$ip = $_SERVER["REMOTE_ADDR"]; //file_put_contents($file, "ip:" . $ip . PHP_EOL,FILE_APPEND); //echo $ip; //$querystring = $_SERVER["QUERY_STRING"]; //file_put_contents($file, "querystring:" . $querystring . PHP_EOL,FILE_APPEND); // 微信token認證 $signature = $_GET["signature"]; //file_put_contents($file, "signature:" . $signature . PHP_EOL,FILE_APPEND); $timestamp = $_GET["timestamp"]; //file_put_contents($file,"timestamp:" . $timestamp . PHP_EOL,FILE_APPEND); $nonce = $_GET["nonce"]; //file_put_contents($file, "nonce:".$nonce . PHP_EOL,FILE_APPEND); $echoStr = $_GET["echostr"]; //file_put_contents($file, "echostr:" . $echoStr . PHP_EOL,FILE_APPEND); // 你的設定Token $token = "sabre"; // 1)將token、timestamp、nonce三個引數進行字典序排序 $tmpArr = array($token,$timestamp,$nonce); sort($tmpArr); // 2)將三個引數字串拼接成一個字串進行sha1加密 $str = implode($tmpArr); $sign = sha1($str); //file_put_contents($file, "sign:" . $sign . PHP_EOL,FILE_APPEND); //file_put_contents($file, "signature:" . $signature . PHP_EOL,FILE_APPEND); /*if($data = file_get_contents($file)){; // 這個函式支援版本(PHP 4 >= 4.3.0, PHP 5) echo "寫入檔案的內容是:$data" . "\r\n"; } */ // 3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信 //file_put_contents($file, "signature長度 :" . strlen($signature) . PHP_EOL,FILE_APPEND); //file_put_contents($file, "sign長度:" . strlen($sign) . PHP_EOL,FILE_APPEND); if ($sign == $signature) { //echo $echostr; //return true ; //ob_clean(); //file_put_contents($file, "echoStr:" . $echoStr . PHP_EOL,FILE_APPEND); echo $echoStr; } ?>
情況二,不帶日誌,相對簡潔一些的
<?php //echo "測試頁面3"; // 微信token認證 $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $echoStr = $_GET["echostr"]; // 你的設定Token $token = "sabre"; // 1)將token、timestamp、nonce三個引數進行字典序排序 $tmpArr = array($token,$timestamp,$nonce); sort($tmpArr); // 2)將三個引數字串拼接成一個字串進行sha1加密 $str = implode($tmpArr); $sign = sha1($str); // 3)開發者獲得加密後的字串可與signature對比,標識該請求來源於微信 if ($sign == $signature) { //ob_clean(); echo $echoStr; } ?>
情況三,方倍工作室的版本的簡化版,僅保留了token驗證部分
<?php /* 方倍工作室 http://www.cnblogs.com/txw1958/ CopyRight 2013 www.doucube.com All Rights Reserved */ //traceHttp(); echo "測試"; define("TOKEN", "sabre"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->valid(); class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; if($this->checkSignature()){ ob_clean(); echo $echoStr; exit; } } private function checkSignature() { $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); sort($tmpArr); $tmpStr = implode( $tmpArr ); $tmpStr = sha1( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } ?>