注意: 1.官网下载的sdk,pkcs7Encoder.php第93行要注释掉 2.微信发过来的xml多了webwx_msg_cli_ver_0x1,要替换掉, $sMsg=str_replace(webwx_msg_cli_ver_0x1,,$sMsg); 3.页面注意不能有警告信息 无 ?php//ini_set('display_errors', 1); //$_GET[] 参数注意判
注意:
<?php //ini_set('display_errors', 1); //$_GET[] 参数注意判断有无,否则页面报错,接口失败,我这里偷懒就没做判断了 (isset($_GET['echostr']) && $_GET['echostr']) ? $_GET['echostr'] : ''; define("TOKEN", "mytoken"); include_once "wxBizMsgCrypt.php";//加密解密类 $wechatObj = new wechatCallbackapiTest(); if ($wechatObj->valid()) { $wechatObj->responseMsg(); } class wechatCallbackapiTest { public $encodingAesKey = "请替换填写"; //EncodingAESKey(消息加解密密钥) public $encrypt_type = ""; //加密类型 public $appId = "请替换填写"; //AppID(应用ID) public $wxcpt; //加密解密类 public $token = TOKEN; public function valid() { //valid signature , option if ($this->checkSignature()) { echo $_GET["echostr"]; return true; } return false; } /* 入口程序 */ public function responseMsg() { $msg_signature = $_GET['msg_signature']; $timestamp = $_GET['timestamp']; $nonce = $_GET['nonce']; $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; $encrypt_type = (isset($_GET['encrypt_type']) && $_GET['encrypt_type']) ? $_GET['encrypt_type'] : "";//加密方式 安全模式:aes 明文模式:空或其他 $this->encrypt_type = $encrypt_type; //extract post data if (!empty($postStr)) { libxml_disable_entity_loader(true); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $toUsername = $postObj->ToUserName;//原始公众号 //通过原始公众号查找保存在本地数据库的密匙等信息..... //do Something.... //如果是加密模式 if($encrypt_type == "aes"){ $postObj = ""; $wxcpt = new WXBizMsgCrypt($this->token, $this->encodingAesKey, $this->appId); $this->wxcpt = $wxcpt; $sMsg = ""; //解析之后的明文 $errCode = $this->wxcpt->DecryptMsg($msg_signature, $timestamp, $nonce, $postStr, $sMsg);//返回0 解密成功 //微信bugwebwx_msg_cli_ver_0x1 $sMsg = str_replace("webwx_msg_cli_ver_0x1","",$sMsg);//坑爹啊,谁搞的这玩意 if ($errCode == 0) { $postObj = simplexml_load_string($sMsg, 'SimpleXMLElement', LIBXML_NOCDATA); } else { echo $errCode . "\n\n"; } } $fromUsername = $postObj->FromUserName; $keyword = trim($postObj->Content); $time = time(); switch ($keyword) { case "1": $contentStr = "你妹"; break; case "2": $contentStr = "你大爷"; break; default : $contentStr = "坑爹啊"; break; } $textTpl = "<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[%s]]></MsgType><Content><![CDATA[%s]]></Content></xml>"; if (!empty($keyword)) { $msgType = "text"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); $this->sendMsg($resultStr);//输出 } else { echo "Input something..."; } } else { echo ""; exit; } } /* 加密并回复消息 */ public function sendMsg($resultStr){ if($this->encrypt_type == "aes"){ $sEncryptMsg = ""; //xml格式的密文 $timestamp = $_GET['timestamp']; $nonce = $_GET['nonce']; $errCode = $this->wxcpt->encryptMsg($resultStr, $timestamp, $nonce, $sEncryptMsg); file_put_contents('000.txt', date("H:i:s").$resultStr); //调试 //echo $resultStr;exit;//明文输出 if ($errCode == 0) { echo $sEncryptMsg;//加密输出 exit; } else { echo $errCode . "\n\n"; } }else{ echo $resultStr;//明文输出 exit; } } /* 验证有效性 */ private function checkSignature() { // you must define TOKEN by yourself if (!defined("TOKEN")) { throw new Exception('TOKEN is not defined!'); } $signature = $_GET["signature"]; $timestamp = $_GET["timestamp"]; $nonce = $_GET["nonce"]; $token = TOKEN; $tmpArr = array($token, $timestamp, $nonce); // use SORT_STRING rule sort($tmpArr, SORT_STRING); $tmpStr = implode($tmpArr); $tmpStr = sha1($tmpStr); if ($tmpStr == $signature) { return true; } else { return false; } } } ?>