PHP微信开发之微信消息自动回复下所遇到的坑


Posted in PHP onMay 09, 2016

微信回复原理:

当普通微信用户向公众账号发送消息时,微信服务器首先收到用户发送的消息;

然后将用户信息和消息打包成XML格式的数据包,再将这个XML数据包通过POST方法提交到开发者设置的URL上。

疑问一:为何使用$GLOBALS["HTTP_RAW_POST_DATA"]保存POST过来的数据,而非$_POST数组?

回答:

POST只能保存标准的数据类型,对于XML、SOAP或Application/Octet-steam之类的内容则无法解析。

而$GLOBALS["HTTP_RAW_POST_DATA"]和$_POST是一样的,如果POST过来的数据PHP能够识别,则可以用$GLOBALS["HTTP_RAW_POST_DATA"]来接收。

疑问二:simplexml_load_file()各参数和返回值是什么?

回答:

参数含义

string:需要处理的XML字符串。

class:用来指定新对象,通常设置为"SimpleXMLElement",生成一个简单XML元素的类。

options:指定附加的Libxml参数,通常设置为常量LIBXML_NOCDATA,表示把CDATA设置为文本节点。

ns:一般省略

is_prefix:一般省略

函数执行完成后返回SimpleXMLElement类的一个对象。

功能:公众号只接受文字消息,且做出相应的文字回复。

<span style="font-family:Courier New;font-size:14px;"><?php 
define("TOKEN","weixin"); 
$weixinObj = new Wechat(); 
$weixinObj->valid(); 
class Wechat{ 
public function valid(){ 
$echoStr = $_GET['echostr']; 
//如果是第一次接入 
if($this->checkSignature() && $echoStr ){ 
echo $echoStr; 
exit; 
}else{ 
$this->responseMsg(); 
} 
} 
//校验方法 
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; 
} 
} 
/* 普通文本消息 
<xml> 
<ToUserName><![CDATA[toUser]]></ToUserName> 
<FromUserName><![CDATA[fromUser]]></FromUserName> 
<CreateTime>1348831860</CreateTime> 
<MsgType><![CDATA[text]]></MsgType> 
<Content><![CDATA[this is a test]]></Content> 
</xml> 
*/ 
public function responseMsg(){ 
//获取微信服务器POST请求中的数据 
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 
if( !empty($postStr) ){ 
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 
$fromUser = $postObj->FromUserName; 
$toUser = $postObj->ToUserName; 
$keyword = trim($postObj->Content); 
$time = time(); 
$template = "<xml> 
<ToUserName><![CDATA[%s]]></ToUserName> 
<FromUserName><![CDATA[%s]]></FromUserName> 
<CreateTime>%s</CreateTime> 
<MsgType><![CDATA[%s]]></MsgType> 
<Content><![CDATA[%s]]></Content> 
</xml>"; 
if( strtolower($postObj->MsgType)!='text' ){ 
$msgType = "text"; 
$content = "我只接受文本消息"; 
}else{ 
$msgType = "text"; 
if( !empty($keyword) ){ 
$content = "您发送的消息是:".$postObj->Content; 
}else{ 
$content = "请输入关键字";//消息为空 
} 
} 
$info = sprintf($template, $fromUser, $toUser, $time, $msgType, $content); 
echo $info; 
}else{ 
echo ""; 
exit; 
} 
} 
}</span>

功能:公众号只接受图片消息,且做出相应的文字回复。

<span style="font-family:Courier New;font-size:14px;"><?php 
define("TOKEN","weixin"); 
$weixinObj = new Wechat(); 
$weixinObj->valid(); 
class Wechat{ 
public function valid(){ 
$echoStr = $_GET['echostr']; 
//如果是第一次接入 
if($this->checkSignature() && $echoStr ){ 
echo $echoStr; 
exit; 
}else{ 
$this->responseMsg(); 
} 
} 
//校验方法 
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; 
} 
} 
/* 接收图片消息格式 
<xml> 
<ToUserName><![CDATA[toUser]]></ToUserName> 
<FromUserName><![CDATA[fromUser]]></FromUserName> 
<CreateTime>1348831860</CreateTime> 
<MsgType><![CDATA[image]]></MsgType> 
<PicUrl><![CDATA[this is a url]]></PicUrl> 
<MediaId><![CDATA[media_id]]></MediaId> 
<MsgId>1234567890123456</MsgId> 
</xml> 
*/ 
public function responseMsg(){ 
//获取微信服务器POST请求中的数据 
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; 
if( !empty($postStr) ){ 
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); 
$fromUser = $postObj->FromUserName; 
$toUser = $postObj->ToUserName; 
$time = time(); 
$msgType= $postObj->MsgType; 
$picUrl = $postObj->PicUrl; 
$mediaId = $postObj->MediaId; 
$template = "<xml> 
<ToUserName><![CDATA[%s]]></ToUserName> 
<FromUserName><![CDATA[%s]]></FromUserName> 
<CreateTime>%s</CreateTime> 
<MsgType><![CDATA[%s]]></MsgType> 
<Content><![CDATA[%s]]></Content> 
</xml>"; 
if( strtolower($msgType)!='image' ){ 
$msgType = "text"; 
$content = "我只接受图片消息"; 
}else{ 
$msgType = "text"; 
if( !empty( $picUrl ) ){ 
$content = "图片链接为:".$picUrl."\n"; 
$content .= "媒体id:".$mediaId; 
}else{ 
$content = "请发送图片";//消息为空 
} 
} 
$info = sprintf($template, $fromUser, $toUser, $time, $msgType, $content); 
echo $info; 
}else{ 
echo ""; 
exit; 
} 
} 
}</span>

以上是小编给大家分享的微信消息自动回复下所遇到的坑的相关知识,希望对大家有所帮助!

PHP 相关文章推荐
FleaPHP的安全设置方法
Sep 15 PHP
zf框架的数据库追踪器使用示例
Mar 13 PHP
PHP记录搜索引擎蜘蛛访问网站足迹的方法
Apr 15 PHP
6个超实用的PHP代码片段
Aug 10 PHP
php实现批量删除挂马文件及批量替换页面内容完整实例
Jul 08 PHP
CI框架实现优化文件上传及多文件上传的方法
Jan 04 PHP
php可变长参数处理函数详解
Feb 22 PHP
解决php-fpm.service not found问题的办法
Jun 06 PHP
PHP实现十进制数字与二十六进制字母串相互转换操作示例
Aug 10 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
Nov 21 PHP
PHP设计模式之适配器模式(Adapter)原理与用法详解
Dec 12 PHP
ThinkPHP类似AOP思想的参数验证的实现方法
Dec 18 PHP
php简单复制文件的方法
May 09 #PHP
win10环境PHP 7 安装配置【教程】
May 09 #PHP
php文件操作小结(删除指定文件/获取文件夹下的文件名/读取文件夹下图片名)
May 09 #PHP
php自动提交表单的方法(基于fsockopen与curl)
May 09 #PHP
php简单实现多语言切换的方法
May 09 #PHP
深入浅析PHP无限极分类的案例教程
May 09 #PHP
实例讲解php数据访问
May 09 #PHP
You might like
文件上传的实现
2006/10/09 PHP
js检测客户端不是firefox则提示下载
2007/04/07 Javascript
extjs fckeditor集成代码
2009/05/10 Javascript
在jQuery1.5中使用deferred对象 着放大镜看Promise
2011/03/12 Javascript
分享20款好玩的jQuery游戏
2011/04/17 Javascript
关于hashchangebroker和statehashable的补充文档
2011/08/08 Javascript
javascript之典型高阶函数应用介绍
2013/01/10 Javascript
javascript:文字不间断向左移动的实例代码
2013/08/08 Javascript
js同比例缩放图片的小例子
2013/10/30 Javascript
在JavaScript中构建ArrayList示例代码
2014/09/17 Javascript
使用jQuery jqPlot插件绘制柱状图
2014/12/18 Javascript
JS获取iframe中longdesc属性的方法
2015/04/01 Javascript
JavaScript返回上一页的三种方法及区别介绍
2015/07/04 Javascript
基于JS模仿windows文件按名称排序效果
2016/06/29 Javascript
基于d3.js实现实时刷新的折线图
2016/08/03 Javascript
D3.js中强制异步文件读取同步的几种方法
2017/02/06 Javascript
jQuery 判断元素整理汇总
2017/02/28 Javascript
详谈js遍历集合(Array,Map,Set)
2017/04/06 Javascript
Javascript中从学习bind到实现bind的过程
2018/01/05 Javascript
vue实现自定义多选与单选的答题功能
2018/07/05 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
2019/08/27 Javascript
如何管理Vue中的缓存页面
2021/02/06 Vue.js
[02:56]DOTA2英雄基础教程 巨魔战将
2013/12/10 DOTA
网站渗透常用Python小脚本查询同ip网站
2017/05/08 Python
python利用有道翻译实现&quot;语言翻译器&quot;的功能实例
2017/11/14 Python
使用python对excle和json互相转换的示例
2018/10/23 Python
python 递归调用返回None的问题及解决方法
2020/03/16 Python
python实现简单猜单词游戏
2020/12/24 Python
Pycharm创建python文件自动添加日期作者等信息(步骤详解)
2021/02/03 Python
Java的for语句中break, continue和return的区别
2013/12/19 面试题
编写一个 C 函数,该函数在一个字符串中找到可能的最长的子字符串,且该字符串是由同一字符组成的
2015/07/23 面试题
2014学年自我鉴定
2014/02/23 职场文书
学校食品安全实施方案
2014/06/14 职场文书
2014年市场部工作总结
2014/11/25 职场文书
幼儿园综治宣传月活动总结
2015/05/07 职场文书
mysql left join快速转inner join的过程
2021/06/30 MySQL