预备篇
1、申请微信公众账号:
微信公众平台地址:https://mp.weixin.qq.com/
微信开发官方说明文档:http://mp.weixin.qq.com/wiki/home/
微信开发测试公众账号申请:http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login (打开后点击登录,用自己的微信号扫一扫就会发放一个相应的测试公众账号,此账号拥有所有接口权限,仅供程序员测试使用)
2、网站空间
如果自己有的话就忽略,没有的可以使用阿里云,领券地址:死戳这里
配置篇
1、代码上传
将下列代码保存到一个index.php的文件中,并将此文件示例文件上传到SAE代码管理库中(代码下载)
<?php
/**
* 作者:smalle
* 网址:http://blog.csdn.net/oldinaction
* 微信公众号:smallelife
*/
//定义 TOKEN(要与开发者中心配置的TOKEN一致)
define("TOKEN", "smalle");
//实例化对象
$wechatObj = new wechatCallbackapiTest();
//调用函数
if (isset($_GET['echostr'])) {
$wechatObj->valid();
}else{
$wechatObj->responseMsg();
}
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
public function responseMsg()
{
// $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; // 虚拟机可能禁止register_globals导致无法获取body数据
$postStr = file_get_contents("php://input");
if (!empty($postStr)){
libxml_disable_entity_loader(true);//安全防护
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$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>";
if(!empty( $keyword ))
{
$msgType = "text";
//用户给公众号发消息后,公众号被动(自动)回复的消息内容
$contentStr = "欢迎来到微信公众平台开发世界!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
private function checkSignature()
{
if (!defined("TOKEN")) {
throw new Exception('TOKEN is not defined!');
}
$signature = $_GET["signature"];
$timestamp = $_GET["timestamp"];
$nonce = $_GET["nonce"];
$token = TOKEN;
$tmpArr = array($token, $timestamp, $nonce);
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
}
?>
2、开发者中心服务器配置
进入公众平台后点击开发者中心,在服务器配置栏按如下图进行配置(URL改为自己SAE项目的URL地址),配置完成后保存并点击启用(注意:一定要先上传以上代码到空间再来配置,否则无法通过验证就提示配置失败)
3、示例结果展示
上面的代码实现的是一个发送任意文本消息后,公众号都会回复一句“欢迎来到微信公众平台开发世界!”
4、代码结构分析
第9行【define(“TOKEN”, “smalle”);】:定义了一个TOKEN(令牌),其值与在开发者中心服务器配置的Token要保持一致。
第11行【
w
e
c
h
a
t
O
b
j
=
n
e
w
w
e
c
h
a
t
C
a
l
l
b
a
c
k
a
p
i
T
e
s
t
(
)
;
】
:
示
例
化
一
个
w
e
c
h
a
t
C
a
l
l
b
a
c
k
a
p
i
T
e
s
t
类
对
象
,
w
e
c
h
a
t
C
a
l
l
b
a
c
k
a
p
i
T
e
s
t
类
中
包
含
三
个
函
数
,
v
a
l
i
d
(
)
、
r
e
s
p
o
n
s
e
M
s
g
(
)
回
应
消
息
、
c
h
e
c
k
S
i
g
n
a
t
u
r
e
(
)
检
查
签
名
。
我
们
刚
开
始
需
要
关
注
的
就
是
r
e
s
p
o
n
s
e
M
s
g
(
)
中
的
内
容
。
第
40
−
51
行
【
wechatObj = new wechatCallbackapiTest();】 :示例化一个wechatCallbackapiTest类对象,wechatCallbackapiTest类中包含三个函数,valid()、responseMsg()回应消息、checkSignature()检查签名。我们刚开始需要关注的就是responseMsg()中的内容。 第40-51行【
wechatObj=newwechatCallbackapiTest();】:示例化一个wechatCallbackapiTest类对象,wechatCallbackapiTest类中包含三个函数,valid()、responseMsg()回应消息、checkSignature()检查签名。我们刚开始需要关注的就是responseMsg()中的内容。第40−51行【textTpl = " <![CDATA[%s]]>…";】:是我们自己的服务器发给微信服务器的一个xml数据格式,里面的%s在第56行中动态附加。
第56行【
r
e
s
u
l
t
S
t
r
=
s
p
r
i
n
t
f
(
resultStr = sprintf(
resultStr=sprintf(textTpl, $fromUsername, $toUsername, $time, $msgType,
c
o
n
t
e
n
t
S
t
r
)
;
】
:
第
一
个
参
数
contentStr);】:第一个参数
contentStr);】:第一个参数textTpl指的即时第40行定义的变量,后面的参数依次是上述xml数据格式中的%s。
收发消息原理
1、文字概述
当用户发送消息给公众号时(或某些特定的用户操作引发的事件推送时),会产生一个POST请求,微信服务器将POST消息的XML数据包到开发者填写的URL上,开发者可以在响应包(Get)中返回特定XML结构,来对该消息进行响应(现支持回复文本、图片、图文、语音、视频、音乐)。
2、接收消息XML数据包介绍
以接收文本消息的XML数据包为例。接收文本消息时XML数据格式如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>1348831860</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[this is a test]]></Content>
<MsgId>1234567890123456</MsgId>
</xml>
相关参数:
参数 描述
ToUserName 开发者微信号
FromUserName 发送方帐号(一个OpenID)
CreateTime 消息创建时间 (整型)
MsgType 消息类型(text)
Content 文本消息内容
MsgId 消息id,64位整型
3、被动回复消息XML数据包介绍
以被动回复文本消息的XML数据包为例。回复文本消息时XML数据格式如下:
<xml>
<ToUserName><![CDATA[toUser]]></ToUserName>
<FromUserName><![CDATA[fromUser]]></FromUserName>
<CreateTime>12345678</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[你好]]></Content>
</xml>
相关参数:
参数 是否必须 描述
ToUserName 是 接收方帐号(收到的OpenID)
FromUserName 是 开发者微信号
CreateTime 是 消息创建时间 (整型)
MsgType 是 text
Content 是 回复的消息内容(换行:在content中能够换行,微信客户端就支持换行显示)
4、图解
微信用户给公众号发送一条"this is a test"消息,微信服务器和我的服务器之间以xml格式在后台进行数据传输,最终将"你好"返回给用户。