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 相关文章推荐
Zend引擎的发展 [15]
Oct 09 PHP
PHP define函数的使用说明
Aug 27 PHP
10款实用的PHP开源工具
Oct 23 PHP
深入浅析yii2-gii自定义模板的方法
Apr 26 PHP
php如何执行非缓冲查询API
Jul 22 PHP
PHP页面输出搜索后跳转下一页的处理方法
Sep 30 PHP
PHP实现的激活用户注册验证邮箱功能示例
Jun 06 PHP
PHP mysqli事务操作常用方法分析
Jul 22 PHP
php封装db类连接sqlite3数据库的方法实例
Dec 19 PHP
php校验公钥是否可用的实例方法
Sep 17 PHP
Laravel 5.5 异常处理 &amp; 错误日志的解决
Oct 17 PHP
PHP的图像处理实例小结【文字水印、图片水印、压缩图像等】
Dec 20 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
php生成静态文件的多种方法分享
2012/07/17 PHP
php后台如何避免用户直接进入方法实例
2013/10/15 PHP
PHP防止post重复提交数据的简单例子
2014/06/07 PHP
ThinkPHP模板Switch标签用法示例
2014/06/30 PHP
ThinkPHP结合AjaxFileUploader实现无刷新文件上传的方法
2014/10/29 PHP
PHP随机数 C扩展随机数
2016/05/04 PHP
thinkPHP5.0框架模块设计详解
2017/03/18 PHP
Kindeditor编辑器添加图片上传水印功能(php代码)
2017/08/03 PHP
实例:尽可能写友好的Javascript代码
2006/10/09 Javascript
ajaxControlToolkit AutoCompleteExtender的用法
2008/10/30 Javascript
flash javascript之间的通讯方法小结
2008/12/20 Javascript
JQuery DataTable删除行后的页面更新利用Ajax解决
2013/05/17 Javascript
JQuery中form验证出错信息的查看方法
2013/10/08 Javascript
jQuery实现固定在网页顶部的菜单效果代码
2015/09/02 Javascript
基于Bootstrap实现的下拉菜单手机端不能选择菜单项的原因附解决办法
2016/07/22 Javascript
详解ES6 系列之异步处理实战
2018/10/26 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
Vue路由模块化配置的完整步骤
2019/08/14 Javascript
使用Webpack提升Vue.js应用程序的4种方法(翻译)
2019/10/09 Javascript
[01:37]TI4西雅图DOTA2前线报道 VG拿下首胜教练357给出获胜秘诀
2014/07/10 DOTA
Linux系统上Nginx+Python的web.py与Django框架环境
2015/12/25 Python
python TKinter获取文本框内容的方法
2018/10/11 Python
浅谈Python访问MySQL的正确姿势
2020/01/07 Python
Django 多对多字段的更新和插入数据实例
2020/03/31 Python
Pandas把dataframe或series转换成list的方法
2020/06/14 Python
纯CSS3打造动感漂亮时尚的扇形菜单
2014/03/18 HTML / CSS
运动鞋、街头服装、手表和手袋的实时市场:StockX
2020/11/25 全球购物
介绍一下Cookie和Session及他们之间的区别
2012/11/20 面试题
银行会计职员个人的自我评价
2013/09/29 职场文书
证婚人搞笑证婚词
2014/01/10 职场文书
暑期社会实践感言
2014/02/25 职场文书
幼儿教师寄语集锦
2014/04/03 职场文书
医师定期考核实施方案
2014/05/07 职场文书
2015年工商所工作总结
2015/05/21 职场文书
文艺晚会开场白
2015/05/29 职场文书
生活小常识广播稿
2015/08/19 职场文书