在使用PHP进行公众号开发时,如果出现消息部分丢失的话,很可能是下载到旧的sdk。
这种情况一般出现在从网上下载SDK而不是从官方下载sdk,导致下载到旧的sdk。而旧的sdk中有bug会导致公众号消息解密失败,从而漏掉消息。
官方提供的旧的sdk中的 checkSignature 函数,导致回复的消息经常性的丢失。 官方示例代码中的 checkSignature 函数:
//这里是官方旧的sdk代码,是错误的,别复制黏贴。
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;
}
}
其中的 sort($tmpArr);
修改为 sort($tmpArr, SORT_STRING);
正确代码为:
private function checkSignature() {
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
这个bug的出现时因为sort函数默认把每一项按常规顺序排列(Standard ASCII,不改变类型)的,因此解密时会出现偶现性解密失败。而SORT_STRING参数是把每一项作为字符串来处理,使用类似 natsort() 的自然排序。