参考微信公众平台开发者文档
https://mp.weixin.qq.com/wiki/8/f9a0b8382e0b77d87b3bcc1ce6fbc104.html
- 下载示例代码
- 将示例代码通过FTP传至自己的服务器
- 配置域名和Token(我这里是dandan)
- 随机生成EncodingAESKey
- 验证
新定义一个方法
public function index(){
if (isset($_GET['echostr'])){
$this->valid();
} else {
$this->responseMsg();
}
注释掉
//$wechatObj->valid();
新加一行
$wechatObj->index();
开发者文档->消息管理->被动回复消息
微信的示例代码里面自带了一个回复文本消息的XML数据包
if(!empty( $keyword ))
{
$msgType = "text";
$contentStr = "Welcome to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
示例代码改到这一步的话,你发送任意一个字符给公众号,他都会回复你
Welcome to wechat world!
对比一下文本消息、图片消息,语音消息的数据包结构
文本消息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
图片消息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<Image>
<MediaId><![CDATA[media_id]]></MediaId>
</Image>
</xml>
语音消息
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Voice>
<MediaId><![CDATA[media_id]]></MediaId>
</Voice>
</xml>
可以发现MsgType代表的就是消息类型,语音消息和图片消息都有一个MediaID。
图片、语音、音乐、还有视频。这些都属于媒体,上传到微信服务器后都会生成一个MediaID,相当于每个文件的"身份证"。
微信的示例代码中没有回复图片消息和语音消息的数据包,所以需要导入。
$imgTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
</xml>";
$voiceTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Voice>
<MediaId><![CDATA[%s]]></MediaId>
</Voice>
</xml>";
还有一个就是默认的示例代码中没有消息类型,所以需要添加一个变量。
$type = $postObj->MsgType;
然后用If 语句判断消息类型做出相应的回复。
- 用户发送文本消息回复给用户 文本消息+'用户发送的文本'。
用户发送图片消息回复给用户同一张图片。
-
用户发送语音消息回复给用户同样的语音消息。
if($type == 'text') { $str = '文本消息' . $keyword; $MsgType = 'text'; $echo = sprintf($textTpl,$fromUsername,$toUsername,$time,$MsgType,$str); }else if ($type == 'image'){ $MsgType = 'image'; $echo = sprintf($imgTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId); }else if ($type =='voice'){ $MsgType = 'voice'; $echo = sprintf($voiceTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId); }
这里要注意的是sprintf()里面需要交换fromUsername和toUsername的顺序,其他的变量顺序不能颠倒,如果颠倒则公众号无法正常回复。因为fromUsername既代表用户发给你,也代表你发送给用户,toUsername同理,微信里面还有很多东西可以去尝试比如语音识别接口等等。
完整代码如下
<?php
/**
* wechat php test
*/
//define your token
define("TOKEN", "dandan");
$wechatObj = new wechatCallbackapiTest();
//$wechatObj->valid();
$wechatObj->index();
class wechatCallbackapiTest
{
public function index(){
if (isset($_GET['echostr'])){
$this->valid();
} else {
$this->responseMsg();
}
}
public function valid()
{
$echoStr = $_GET["echostr"];
//valid signature , option
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
public function responseMsg()
{
//get post data, May be due to the different environments
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
//extract post data
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$type = $postObj->MsgType;
$time = time();
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Content><![CDATA[%s]]></Content>
<FuncFlag>0</FuncFlag>
</xml>";
$imgTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Image>
<MediaId><![CDATA[%s]]></MediaId>
</Image>
</xml>";
$voiceTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[%s]]></MsgType>
<Voice>
<MediaId><![CDATA[%s]]></MediaId>
</Voice>
</xml>";
if($type == 'text') {
$str = '文本消息' . $keyword;
$MsgType = 'text';
$echo = sprintf($textTpl,$fromUsername,$toUsername,$time,$MsgType,$str);
}else if ($type == 'image'){
$MsgType = 'image';
$echo = sprintf($imgTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId);
}else if ($type =='voice'){
$MsgType = 'voice';
$echo = sprintf($voiceTpl,$fromUsername,$toUsername,$time,$MsgType,$postObj->MediaId);
}
echo $echo;
}else {
echo "";
exit;
}
}
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;
}
}
}
?>