토큰이 인증된 후 구독 계정으로 메시지가 전송되지만 메시지는 반환되지 않습니다.
하드 디버깅을 통해 얻은 해결 방법은 다음과 같습니다.
먼저 토큰 인증:
제가 작성한 토큰이 계속 검증에 실패하여 오랫동안 찾아보았으나 버그가 발견되지 않았습니다. 정말 다른 방법이 없어서 공식 샘플 코드를 사용했습니다. 그리고 샘플 코드 디버깅을 통해 피를 토하게 만드는 버그(버그 아님)를 발견했습니다.
토큰 검증에는 문자 인코딩 형식이 필요한 것 같습니다! ! ! !
공식 샘플 코드가 서버에 직접 업로드되고, 토큰이 직접 전달됩니다!
공식 샘플 코드를 UTF-8 형식으로 변경한 후 업로드해서 덮어썼는데 토큰이 실패했어요! 실패하다! 실패하다!
나중에 작성한 내용을 ANSI 형식으로 변경했는데 여전히 토큰이 실패했습니다! 취했어, 취했어! 그런 다음 공식 샘플 코드를 사용해야 합니다. 여기서 토큰은 일회성 핸드셰이크 검증이며, 한 번 검증한 후에는 더 이상 필요하지 않다고 말씀드립니다.
자, 다시 얘기가 빗나간 것 같은 주제로 돌아가겠습니다... orz
토큰 검증 후 공식 샘플 코드를 직접 사용해 빠르게 진행했습니다. 내 구독 계정을 테스트해 보니 결과가... .보내는 메시지는 물 쏟아진 것 같고 아무것도 돌아오지 않습니다...orz
버그도 찾아보고, 여러 그룹에 물어보고, 검색해봤습니다. ... 99번, 81번의 노력 끝에 이 블로거가 마침내 문제를 발견했습니다(이것은 제가 개발한 것이지 전부는 아닙니다. 다른 버그가 있으면 편하게 소통해주세요):
1. 가장 쉽게 간과되는 버그는 공식 샘플 코드가 작성된 responseMsg() 함수를 전혀 호출하지 않는다는 것입니다!
2. 이전 토큰 코드인 $wechatObj->valid();를 주석 처리합니다. 토큰 확인 코드에 echo $echostr이 있기 때문에 responseMsg() 함수의 echo $resultStr;(라인 56)은 혼란스러운 xml 형식이 되어 다시 입력될 때 인식되지 않습니다. WeChat 서버(xml 형식만 인식할 수 있는 것 같습니다. json 형식도 인식할 수 있습니다). (토큰 검증은 핸드셰이크 검증입니다. 개발자 검증 후에는 더 이상 필요하지 않습니다. 깔끔한 코드에서 사라지게 놔두세요...)
3. 여전히 가장 역겨운 버그는 문자 인코딩입니다. 문제! orz...xml에는 UTF-8 인코딩이 필요하므로 샘플 코드를 다시 UTF-8 인코딩으로 변경하세요! 이 버그는 나를 무너지게 만든다! ! !
다음은 제가 수정한 코드입니다. 정상적으로 실행되고 버그도 없습니다. 필요하시면 참고하시면 됩니다.
<?php /** * wechat php test */ //define your token define("TOKEN", "codcodog"); $wechatObj = new wechatCallbackapiTest(); //$wechatObj->valid(); $wechatObj->responseMsg(); class wechatCallbackapiTest { public function valid() { $echoStr = $_GET["echostr"]; //valid signature , option if($this->checkSignature()){ header('content-type:text'); echo $echoStr; exit; } } public function responseMsg() { //get post data, May be due to the different environments $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //$postStr = file_get_contents("php://input"); file_put_contents("log.txt",$postStr,FILE_APPEND ); //extract post data if (!empty($postStr)){ /* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection, the best way is to check the validity of xml by yourself */ libxml_disable_entity_loader(true); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $fromUsername = $postObj->FromUserName; //用户 $toUsername = $postObj->ToUserName; //公众平台 $keyword = trim($postObj->Content); $time = time(); $textTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag></FuncFlag> </xml>"; if(!empty( $keyword )) { $msgType = "text"; $contentStr = "Welcome to wechat world!"; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr); echo $resultStr; }else{ echo "Input something..."; } }else { echo ""; 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 = sha( $tmpStr ); if( $tmpStr == $signature ){ return true; }else{ return false; } } } ?>
위 내용은 PHP WeChat 구독 계정 개발을 위해 편집자가 공유한 솔루션입니다. 토큰 확인 후 메시지는 자동으로 구독 계정으로 전송되지만 마음에 드셨으면 좋겠습니다.
위 내용은 토큰 인증 후 구독 계정으로 메시지가 자동으로 전송되지만 관련 내용을 포함하여 PHP WeChat 구독 계정 개발 시 메시지가 반환되지 않는 문제를 소개합니다. PHP 튜토리얼에 관심이 있는 친구들에게 도움이 되길 바랍니다. .