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 相关文章推荐
用文本文件实现的动态实时发布新闻的程序
Oct 09 PHP
PHP设计模式之结构模式的深入解析
Jun 13 PHP
php中动态变量用法实例
Jun 10 PHP
php提取身份证号码中的生日日期以及验证是否为成年人的函数
Sep 29 PHP
PHP Try-catch 语句使用技巧
Feb 28 PHP
php cookie 详解使用实例
Nov 03 PHP
thinkPHP5.0框架URL访问方法详解
Mar 18 PHP
php实现用户注册密码的crypt加密
Jun 08 PHP
PHP有序表查找之二分查找(折半查找)算法示例
Feb 09 PHP
ThinkPHP3.2.3框架实现的空模块、空控制器、空操作,跳转到错误404页面图文详解
Apr 03 PHP
PHP的静态方法与普通方法用法实例分析
Sep 26 PHP
Laravel5.5 视图 - 创建视图和数据传递示例
Oct 21 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 数组遍历顺序理解
2009/09/09 PHP
php 一元分词算法
2009/11/30 PHP
php中防止伪造跨站请求的小招式
2011/09/02 PHP
codeigniter使用技巧批量插入数据实例方法分享
2013/12/31 PHP
详解PHP中的状态模式编程
2015/08/11 PHP
php app支付宝回调(异步通知)详解
2018/07/25 PHP
js自执行函数的几种不同写法的比较
2012/08/16 Javascript
Mac地址验证的javascript代码
2013/11/09 Javascript
js调用浏览器打印模块实现点击按钮触发自定义函数
2014/03/21 Javascript
js实现select跳转功能代码
2014/10/22 Javascript
jQuery动态添加
2016/04/07 Javascript
React Native仿美团下拉菜单的实例代码
2017/08/08 Javascript
vue组件发布到npm简单步骤
2017/11/30 Javascript
js实现动态改变radio状态的方法
2018/02/28 Javascript
React Native 图片查看组件的方法
2018/03/01 Javascript
JavaScript设计模式之观察者模式(发布订阅模式)原理与实现方法示例
2018/07/27 Javascript
解决vue attr取不到属性值的问题
2018/09/18 Javascript
node.js的http.createServer过程深入解析
2019/06/06 Javascript
详解Angular Karma测试的持续集成实践
2019/11/15 Javascript
toString.call()通用的判断数据类型方法示例
2020/08/28 Javascript
基于JavaScript实现轮播图效果
2021/01/02 Javascript
[06:36]吞吞映像top1
2014/06/20 DOTA
Django静态资源URL STATIC_ROOT的配置方法
2014/11/08 Python
django从请求到响应的过程深入讲解
2018/08/01 Python
python简单区块链模拟详解
2019/07/03 Python
Python实现直方图均衡基本原理解析
2019/08/08 Python
pytorch载入预训练模型后,实现训练指定层
2020/01/06 Python
荷兰之家英文站:Holland at Home
2016/10/26 全球购物
护理毕业生自荐信范文
2013/12/22 职场文书
写演讲稿要注意的六件事
2014/01/14 职场文书
文明青少年标兵事迹材料
2014/01/28 职场文书
2014年转正工作总结
2014/11/08 职场文书
中学生思想品德评语
2014/12/31 职场文书
2015年社区文体活动总结
2015/03/25 职场文书
分布式架构Redis中有哪些数据结构及底层实现原理
2022/03/13 Redis
Win10/Win11 任务栏替换成经典样式
2022/04/19 数码科技