原文链接:https://www.whongbin.cn/index/article/detail/id/59.html
前言
今天工作的时候,碰到一个极其无语的关于微信公众号的坑,为此,我语言攻击了腾讯的机器人客服。然而并没有卵用。。。万万没想到,我还是解决了这个问题,并记录下踩坑经历,希望能帮到一些朋友吧。
背景
- 今天不是我第一次开发这部分功能,我想象中的是只要把之前的代码片段
Ctrl+c
,Ctrl+v
就可以了; - 第一次开发这部分,花费了我三个小时;
- 第二次开发这部分,花费了我30分钟,(真的就只是
Ctrl+c
,Ctrl+v
) - 然鹅,事情并没有那么简单
踩坑记
第一步,写验证代码
按照我以往的开发经验看,一下代码直接
Ctrl+c
,Ctrl+v
就可以,事实证明,确实是这样
private function checkSignature()
{
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = 'prettygirl';
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
//使用
public function callbackAction()
{
if ($this->checkSignature()) {
echo $_GET['echostr'];
exit;
}else{
//等会进行补全
}
}
第二步,配置服务器
俗话说:完事开头难,我是真的体会到了啊...我先使用的是测试号验证token正确性,主要就是下面的参数。
- 确保url可以访问,
- 确保你的token和文件中定义的token相同

注意:
这个地方有个大坑,在包含第一步那两个方法的文件中,返回的字符串echostr
官方文档中说要完全原阳返回才能配置成功,但是总有一些不为人知的秘密影响我们的代码...
不瞒你说,我配置这个地方的时候从早晨上班一直到下午三点半才搞出来。惭愧...不说了,再说我又想发起语言攻击了。
我在这个地方一直都不认为是我代码的问题,后来,我发现,真的是代码有问题,或者说是文件有问题。就是这个地方
https://wx1.sinaimg.cn/large/0064eL5bly1fzhuybpm4jj306e0323yb.jpg
以后一定要记住,文件结束符以后,不要留空格,或者干脆就不要写结束符。否则就会出现下面的情况

这TM的的是什么鬼东西,为什么会从第二行输出,原因就是在这个文件中引入了别的文件,刚好,那个文件就有结束符;刚好,那个文件结束符以后还有空行。那你就中奖了啊。
第三部,记得启用,启用后是下面扬子

第四步,写业务代码
搞完上面的步骤,你就可以天马行空的去处理你的业务了,这边撸一个简单的业务代码
// 微信服务器回调
public function wxcallbackAction()
{
if ($this->checkSignature()) {
echo $_GET['echostr'];
}else{
$postStr = file_get_contents('php://input');
if($postStr!=""){
$postArr = $this->xmlToArrayOrObject($postStr,false);
file_put_contents('wx.log', date('Y-m-d H:i:s') .'==='.json_encode($postArr). chr(10), FILE_APPEND | LOCK_EX);
$msgType = trim($postArr['MsgType']);
if($msgType=="event"){
$event = strtolower($postArr['Event']);
$ToUser = $postArr['ToUserName'];
$appid = 'appid';
$secret = 'secret';
$content = "欢迎关注";
file_put_contents('wx.log', date('Y-m-d H:i:s') .'==='.$event. chr(10), FILE_APPEND | LOCK_EX);
if($event == "subscribe"){
$content = "您好,欢迎关注。";
$openid = $postArr['FromUserName']; //oP_Vc0bbhVTzpa2vWUpWCPyCvCy8
$userid = end(explode("_",$postArr['EventKey'])); //qrscene_978562210
}
if($event == "scan"){
$content = "您好,您已关注。";
$openid = $postArr['FromUserName'];
$userid = $postArr['EventKey'];
}
$wxuser = $this->tuserRepository->findByOpenid($openid);
if ($wxuser) {
$content = "欢迎关注。您的微信账号已绑定至 【".$wxuser."】";
}else{
//获取用户信息并进行插库操作
$user = $this->tuserRepository->findByUid($userid);
$user->setOpenid($openid);
$this->tuserRepository->update($user);
$this->refreshObjData();
}
}
$textTpl .= "<xml>\n";
$textTpl .= "<ToUserName><![CDATA[".$openid."]]></ToUserName>\n";
$textTpl .= "<FromUserName><![CDATA[".$ToUser."]]></FromUserName>\n";
$textTpl .= "<CreateTime>".time()."</CreateTime>\n";
$textTpl .= "<MsgType><![CDATA[text]]></MsgType>\n";
$textTpl .= "<Content><![CDATA[".$content."]]></Content>\n";
$textTpl .= "</xml>";
file_put_contents('wx.log', date('Y-m-d H:i:s') .'==='.$textTpl. chr(10), FILE_APPEND | LOCK_EX);
echo $textTpl;
}else{
echo "";
ob_clean();
}
}
exit;
}
后记
算了吧,不说了。都是教训啊
网友评论