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 相关文章推荐
对javascript和select部件的结合运用
Oct 09 PHP
AJAX for PHP简单表数据查询实例
Jan 02 PHP
php 结果集的分页实现代码
Mar 10 PHP
php面向对象全攻略 (十七) 自动加载类
Sep 30 PHP
php 邮件发送问题解决
Mar 22 PHP
PHP_NETWORK_GETADDRESSES: GETADDRINFO FAILED问题解决办法
May 04 PHP
php中substr()函数参数说明及用法实例
Nov 15 PHP
浅谈php正则表达式中的非贪婪模式匹配的使用
Nov 25 PHP
讲解WordPress中用于获取评论模板和搜索表单的PHP函数
Dec 28 PHP
PHP二维数组去重实例分析
Nov 18 PHP
PHP实现将几张照片拼接到一起的合成图片功能【便于整体打印输出】
Nov 14 PHP
基于Laravel 多个中间件的执行顺序详解
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中将ip地址转成十进制数的两种实用方法
2013/08/15 PHP
基于PHP的加载类操作以及其他两种魔术方法的应用实例
2017/08/28 PHP
PHP调用API接口实现天气查询功能的示例
2017/09/21 PHP
基于jquery的一个拖拽到指定区域内的效果
2011/09/21 Javascript
cookie.js 加载顺序问题怎么才有效
2013/07/31 Javascript
jQuery :first选择器使用介绍
2013/08/09 Javascript
浅谈javascript的调试
2015/01/28 Javascript
CSS+JS实现点击文字弹出定时自动关闭DIV层菜单的方法
2015/05/12 Javascript
Javascript原型链的原理详解
2016/01/05 Javascript
js数组常用操作方法小结(增加,删除,合并,分割等)
2016/08/02 Javascript
使用jQuery 操作table 完成单元格合并的实例
2017/12/27 jQuery
vue项目中运用webpack动态配置打包多种环境域名的方法
2019/06/24 Javascript
从零搭一个自用的前端脚手架的方法步骤
2019/09/23 Javascript
Nodejs + Websocket 指定发送及群聊的实现
2020/01/09 NodeJs
vue 使用v-for进行循环的实例代码详解
2020/02/19 Javascript
vscode中的vue项目报错Property ‘xxx‘ does not exist on type ‘CombinedVueInstance<{ readyOnly...Vetur(2339)
2020/09/11 Javascript
python杀死一个线程的方法
2015/09/06 Python
Python selenium 三种等待方式解读
2016/09/15 Python
15行Python代码带你轻松理解令牌桶算法
2018/03/21 Python
python 查找文件名包含指定字符串的方法
2018/06/05 Python
将tensorflow的ckpt模型存储为npy的实例
2018/07/09 Python
python [:3] 实现提取数组中的数
2019/11/27 Python
Python之Sklearn使用入门教程
2021/02/19 Python
Python tkinter实现日期选择器
2021/02/22 Python
浅析HTML5 meta viewport参数
2020/10/28 HTML / CSS
英国最大的老式糖果店:A Quarter Of
2017/04/08 全球购物
车辆维修工自我评价怎么写
2013/09/20 职场文书
厨房工作人员岗位职责
2013/11/15 职场文书
一年级学生期末评语
2014/04/21 职场文书
小学六年级学生评语
2014/04/22 职场文书
观看信仰心得体会
2014/09/04 职场文书
民事诉讼代理授权委托书范本
2014/10/08 职场文书
单位租房协议书范本
2014/12/04 职场文书
筑梦中国心得体会
2016/01/18 职场文书
2019已经过半,你知道年中工作总结该怎么写吗?
2019/07/03 职场文书
java代码实现空间切割
2022/01/18 Java/Android