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 相关文章推荐
PHP5中MVC结构学习
Oct 09 PHP
1.PHP简介
Oct 09 PHP
smarty 原来也不过如此~~呵呵
Nov 25 PHP
PHP 的 __FILE__ 常量
Jan 15 PHP
php session处理的定制
Mar 16 PHP
php判断上传的Excel文件中是否有图片及PHPExcel库认识
Jan 11 PHP
php检测网页是否被百度收录的函数代码
Oct 09 PHP
新浪SAE云平台下使用codeigniter的数据库配置
Jun 12 PHP
php定义参数数量可变的函数用法实例
Mar 16 PHP
PHP数组函数array_multisort()用法实例分析
Apr 02 PHP
PHP实现的mongoDB数据库操作类完整实例
Apr 10 PHP
PHP操作redis实现的分页列表,新增,删除功能封装类与用法示例
Aug 04 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
ThinkPHP3.1的Widget新用法
2014/06/19 PHP
CodeIgniter分页类pagination使用方法示例
2016/03/28 PHP
PHP使用stream_context_create()模拟POST/GET请求的方法
2016/04/02 PHP
用js实现多域名不同文件的调用方法
2007/01/12 Javascript
Sample script that displays all of the users in a given SQL Server DB
2007/06/16 Javascript
地震发生中逃生十大法则
2008/05/12 Javascript
javascript设置连续两次点击按钮时间间隔的方法
2014/10/28 Javascript
总结Javascript中的隐式类型转换
2016/08/24 Javascript
js图片轮播手动切换特效
2017/01/12 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
JS实现动态添加DOM节点和事件的方法示例
2017/04/28 Javascript
angular $watch 一个变量的变化(实例讲解)
2017/08/02 Javascript
JavaScript遍历DOM元素的常见方式示例
2019/02/16 Javascript
详解基于mpvue微信小程序下载远程图片到本地解决思路
2019/05/16 Javascript
vue实现下拉加载其实没那么复杂
2019/08/13 Javascript
使用PreloadJS加载图片资源的基础方法详解
2020/02/03 Javascript
如何优雅地取消 JavaScript 异步任务
2020/03/22 Javascript
vue实现拖拽进度条
2021/03/01 Vue.js
[02:33]2018 DOTA2亚洲邀请赛回顾视频 再次拾起那些美妙的时刻
2018/04/10 DOTA
[52:06]完美世界DOTA2联赛决赛日 Inki vs LBZS 第一场 11.08
2020/11/10 DOTA
python 遍历字符串(含汉字)实例详解
2017/04/04 Python
python opencv之SURF算法示例
2018/02/24 Python
Python判断两个list是否是父子集关系的实例
2018/05/04 Python
mac PyCharm添加Python解释器及添加package路径的方法
2018/10/29 Python
python3多线程知识点总结
2019/09/26 Python
基于python的BP神经网络及异或实现过程解析
2019/09/30 Python
基于Django OneToOneField和ForeignKey的区别详解
2020/03/30 Python
python根据完整路径获得盘名/路径名/文件名/文件扩展名的方法
2020/04/22 Python
详解java调用python的几种用法(看这篇就够了)
2020/12/10 Python
用CSS3实现背景渐变的方法
2015/07/14 HTML / CSS
mysql的最长数据库名,表名,字段名可以是多长
2014/04/21 面试题
白酒业务员岗位职责
2013/12/27 职场文书
调解员先进事迹材料
2014/02/07 职场文书
愚人节活动策划方案
2014/03/11 职场文书
家长会标语
2014/06/24 职场文书
mysql sock文件存储了什么信息
2022/07/15 MySQL