1.基础知识在上一篇地址有讲解和图片,内容大致包括微信开发者模式后台配置、微信公众开发者文档代码详解。
2.本篇将粘贴出包括所有类型在内的消息处理办法,在开发者模式下用代码完成所有编辑模式的基础内容。
3.本篇代码是最基础的微信公众平台功能,大家要掌握如何套用。
4.代码下载点击:http://download.csdn.net/detail/afanxingzhou/8796933
===============================================万能的阉割线================================================================
responseMsg(); //若没有echostr,表示已经通过验证,直接调用responseMsg()方法
}else{
$wechatObj->valid(); //若存在echostr,表示第一次提交验证申请,调用验证方法valid(),判断微信服务器(你的公众号)与网站服务器的是否连通。
}
class wechatCallbackapiTest
{
//验证消息
public function valid()
{
$echoStr = $_GET["echostr"]; //微信服务器发送来的字符串,验证通过,将该字符串原样输出,表示验证成功!
if($this->checkSignature()){ //调用checkSignature()方法检查签名(Signature)是否一致
echo $echoStr;
exit;
}
}
//检查签名
//官网可下载代码——http://mp.weixin.qq.com/wiki/4/2ccadaef44fe1e4b0322355c2312bfa8.html
private function checkSignature()
{
$signature = $_GET["signature"]; //从微信服务器(你的公众号)获取签名
$timestamp = $_GET["timestamp"]; //从微信服务器获取时间戳
$nonce = $_GET["nonce"]; //从微信服务器获取随机数
$token = TOKEN; //将自己核心代码中定义的Token赋值到这里
$tmpArr = array($token, $timestamp, $nonce); //创建数组变量——token+timestamp+nonce
sort($tmpArr, SORT_STRING); //对$tmpArr数组中的 参数 排序;SORT_STRING:把值作为字符串来处理。 $tmpStr = implode($tmpArr); //把数组中的 参数 组合为一个字符串——$tmpStr=$token+$timestamp+$nonce
$tmpStr = sha1($tmpStr); //对字符串$tmpStr进行sha1加密。没有问题的话它会和 $signature 一致
if($tmpStr == $signature){ //验证Token一致,通过验证,返回true
return true;
}else{
return false;
}
}
//================================================请求校验结束,相应消息一步曲开始========================================================
//响应消息
public function responseMsg()
{
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; //获取微信端发送的消息;因为消息是XML数据格式,使用$_POST无法解析,故使用此方法获取
if (!empty($postStr)){ //不是空内容,即有消息发送过来的话,就...
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
/*将$postStr变量进行解析并将 解析后所有数据 赋予 新对象$postObj。
simplexml_load_string():PHP中解析XML的函数;
第一个参数:要解析的XML字符串;
第二个参数:规定新对象所属类——SimpleXMLElement;
第三个参数:将CDATA设置为文本节点,CDATA标签中的文本XML不解析。*/
$RX_TYPE = trim($postObj->MsgType); //从$postObj对象获取消息类型 MsgType。包括文本、图片、语音、视频、位置、链接 + 事件
switch ($RX_TYPE) //根据不同的消息类型,进行不同的处理
{
case "event":
$result = $this->receiveEvent($postObj); //消息类型属于事件(event),调用 接收到事件 方法,将包含所有数据的$postObj传参传过去
break;
case "text":
$result = $this->receiveText($postObj); //用户发送的是 文本,调用 接收到文本 方法
break;
case "image":
$result = $this->receiveImage($postObj); //用户发送的是 图片,调用 接收到图片 方法
break;
case "location":
$result = $this->receiveLocation($postObj); //用户发送的是 地理位置,调用 接收到地理位置 方法
break;
case "voice":
$result = $this->receiveVoice($postObj); //用户发送的是 音频,调用 接收到音频 方法
break;
case "video":
$result = $this->receiveVideo($postObj); //用户发送的是 视频,调用 接收到视频 方法
break;
case "link":
$result = $this->receiveLink($postObj); //用户发送的是 链接,调用 接收到链接 方法
break;
default:
$result = "unknown msg type: ".$RX_TYPE; //未知消息类型
break;
}
echo $result; //输出回复消息,即 发送微信。
}else {
echo "";
exit;
}
}
//===================================================响应消息二部曲开始,核心代码的核心===================================================
//接收事件类型消息——关注;取消关注;扫描带参数二维码;上报地理位置;自定义菜单;点击菜单拉取消息;点击菜单跳转链接
private function receiveEvent($object) //这里的$object来自$postObj————包含解析了微信消息 的对象
{
$content = ""; //为文本变量赋初值
switch ($object->Event) //获取事件类型
{
case "subscribe": //1.关注事件
$content = "欢迎关注柯南大学人民武装学院官方微信公众号,学院微信号正处于开发者试验阶段,欢迎提出宝贵意见! ";//关注后回复给用户的消息
$content .= (!empty($object->EventKey))?("\n来自二维码场景 ".str_replace("qrscene_","",$object->EventKey)):"";
/*第二个content:高级功能,未关注公众号时用户扫描 带参数二维码 回复内容
break;
case "unsubscribe":
$content = "取消关注"; //2.取消关注事件,可以不写content
break;
case "SCAN":
$content = "扫描场景 ".$object->EventKey; //用户已关注公众号,扫描 带参数二维码 回复内容。
break;
case "CLICK": // 自定义菜单事件之拉取消息回复
switch ($object->EventKey) //点击菜单拉取消息,EventKey为 click类型 菜单按钮的key值
{
case "jianjie":
$content = array();
$content[] = array("Title"=>"学院简介","Description"=>"河南大学人民武装学院,是河南省军区与河南大学联合创办,我省唯一的人民武装类高等院校。", "PicUrl"=>"http://henurenwu.duapp.com/images/xueyuan.jpg", "Url" =>"http://henurenwu.duapp.com/about/jianjie.html");
break; //点击"jianjie"click按钮,设置推送 图文消息
case "gonggao":
$content = "最新通告:\n\n恭喜我校本年度有38名同学考取研究生!\n\n更多公告请点击:\n\nhttp://henurenwu.duapp.com/gonggao/xueyuan_gonggao.html";
break; //这里超链接会点击跳转
case "zhaopin":
$content = "点击查看最新招聘信息\n\nhttp://henurenwu.duapp.com/zhaopin/2015-2-14.html";
break;
case "yijianfankui":
$content = "请用‘@+您的意见’的形式将你的意见发送到公众号:";
break;
case "game2048":
$content = "点击将跳转到Game Box,尽情玩耍吧!(游戏过程不消耗流量)点击进入Game Box";
break; //加入超链接符号后文字会添上超链接
default:
$content = "点击菜单:".$object->EventKey; //没有设置key和超链接的 空白按钮,点击后回复消息
break;
}
break;
case "LOCATION": //地理位置事件——对公众号发送位置
$content = "上传位置:纬度 ".$object->Latitude.";经度 ".$object->Longitude; //回复地理位置
break;
case "VIEW":
$content = "跳转链接 ".$object->EventKey; //自定义菜单之跳转链接事件——如果设置了链接就不会回复这句话
break;
default:
$content = "receive a new event: ".$object->Event; //出现新的事件类型回复消息,目前还没出现
break;
}
if(is_array($content)){ //判断$content是否为数组类型——回复信息为图文、音乐类型$content会是数组格式,正好区分
if (isset($content[0]['PicUrl'])){ //图文消息,[0]['PicUrl']:第一条消息的PicUrl列;[1]['PicUrl']表示第二条消息的PicUrl列
$result = $this->transmitNews($object, $content);//调用 传输图文 方法,将包含消息的$postObj,回复消息$content进行传参
}else if (isset($content['MusicUrl'])){ //isset():参数存在且非空时为true
$result = $this->transmitMusic($object, $content);//调用 传输音乐 方法
}
}else{
$result = $this->transmitText($object, $content); //调用 传输文本 方法
}
return $result; //返回结果
}
//接收文本消息
private function receiveText($object)
{
switch ($object->Content) // 关键字回复
{
case "文本": //用户发送内容是“文本”
$content = "这是个文本消息"; //回复消息
break;
case "图文":
case "单图文": //用户发送内容为“单图文”
$content = array(); //图文消息需先创建数组
$content[] = array("Title"=>"单图文标题", "Description"=>"单图文内容", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958"); //单图文,只写一个$content,里面的内容是根据 文本消息XML数据格式 编写
break;
case "多图文":
$content = array();
$content[] = array("Title"=>"多图文1标题", "Description"=>"", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
$content[] = array("Title"=>"多图文2标题", "Description"=>"", "PicUrl"=>"http://d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
$content[] = array("Title"=>"多图文3标题", "Description"=>"", "PicUrl"=>"http://g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
break; //多图文,最多10条
case "音乐":
$content = array("Title"=>"最炫民族风", "Description"=>"歌手:凤凰传奇", "MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3", "HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3"); //音乐,和单图文结构相近,数组内容根据 音乐消息XML数据格式 编写
break;
case "@": //发送消息包含@符号
$content = "感谢您的反馈,让我们一同建设美好的校园!";//回复文本消息
break;
default: //发送文本内容不在上述内容,默认回复以下消息
$content = "请回复其它关键词/从菜单获取信息\n\n".date("Y-m-d H:i:s",time())."\n河南大学人民武装学院";
break;
}
if(is_array($content)){
if (isset($content[0]['PicUrl'])){
$result = $this->transmitNews($object, $content);
}else if (isset($content['MusicUrl'])){
$result = $this->transmitMusic($object, $content);
}
}else{
$result = $this->transmitText($object, $content);
}
return $result;
}
//接收图片消息
private function receiveImage($object)
{
$content = array("MediaId"=>$object->MediaId); //用户向公众号发送图片消息,提取媒体ID。所有的$content都供传参到XML数据中使用
$result = $this->transmitImage($object, $content); //调用 传输图片 方法
return $result;
}
//接收位置消息
private function receiveLocation($object)
{
$content = "你发送的是位置,纬度为:".$object->Location_X.";经度为:".$object->Location_Y.";缩放级别为:".$object->Scale.";位置为:".$object->Label; //从$object对象(=$postObj对象)获取位置参数
$result = $this->transmitText($object, $content); //调用 传输文本 方法
return $result;
}
//接收语音消息
private function receiveVoice($object)
{
if (isset($object->Recognition) && !empty($object->Recognition)){ //用户发送的语音消息,能够识别且识别结果非空(公众号需开通语音识别功能)
$content = "你刚才说的是:".$object->Recognition; //回复文本,将识别结果回复给用户
$result = $this->transmitText($object, $content); //调用 回复文本 方法
}else{
$content = array("MediaId"=>$object->MediaId); //建立数组,内容"MediaId",数据来源:语音消息的MediaId
$result = $this->transmitVoice($object, $content); //调用 传输语音 方法
}
return $result;
}
//接收视频消息
private function receiveVideo($object)
{
$content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->ThumbMediaId, "Title"=>"", "Description"=>"");
$result = $this->transmitVideo($object, $content);
return $result;
}
//接收链接消息
private function receiveLink($object)
{
$content = "你发送的是链接,标题为:".$object->Title.";内容为:".$object->Description.";链接地址为:".$object->Url;
$result = $this->transmitText($object, $content);
return $result;
}
//====================================================修改代码三部曲,官方文档上台========================================================
//回复文本消息
private function transmitText($object, $content) //以下XML数据格式由微信规定,不可更改
{
$textTpl = "
%s
";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
/*将xml格式中的数据分别赋值;
sprintf()为变参函数:第一个参数$textTpl表示对它改变参数;
第二个参数叫$fromUsername(它存的是用户的OpenID),因为数据传输方向掉头了——原来是用户给服务器发送消息,ToUserName表示服务器;现在服务器要发送数据给用户(OpenID),ToUserName表示用户;
第三个参数和第二个参数道理一样;
第四个参数$time:消息创建时间;
第五个参数:消息类型,这里表示文本;
第六个参数:消息内容:服务器向用户发送的消息
*/
return $result; }
//回复图片消息
private function transmitImage($object, $imageArray)
{
$itemTpl = "
//其它数据类型都有独有的部分,独有的部分从前面传参得到
";
$item_str = sprintf($itemTpl, $imageArray['MediaId']);
$textTpl = "
//当然也有通用的部分
%s
$item_str //将独有的部分放置在合适的位置,不能破坏微信文档规定的格式。以下类同
";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
return $result;
}
//回复语音消息
private function transmitVoice($object, $voiceArray)
{
$itemTpl = "
";
$item_str = sprintf($itemTpl, $voiceArray['MediaId']);
$textTpl = "
%s
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
return $result;
}
//回复视频消息
private function transmitVideo($object, $videoArray)
{
$itemTpl = "";
$item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);
$textTpl = "
%s
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
return $result;
}
//回复图文消息
private function transmitNews($object, $newsArray)
{
if(!is_array($newsArray)){
return;
}
$itemTpl = " -
";
$item_str = "";
foreach ($newsArray as $item){
$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
}
$newsTpl = "
%s
%s
$item_str
";
$result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($newsArray));
return $result;
}
//回复音乐消息
private function transmitMusic($object, $musicArray)
{
$itemTpl = "
";
$item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);
$textTpl = "
%s
$item_str
";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
return $result;
}
总结一下,整体来看基础的消息处理代码都在这里了,用图片对整体再进行了解一下
我用注释的方式进行讲解,对大家查阅代码造成一定不便请大家谅解。
有问题或愿意共同进行微信公众平台开发研究的伙伴请联系邮箱:[email protected],欢迎!
因为之前反复修改,导致内容错乱,2015年2月25日00:46:47重新修改。