微信公众平台官方示例分析
wx_sample.php
<?php
/**
* wechat php test
*/
//define your token
//定义常量TOKEN 默认值为“weixin”可修改为3~32个字母
//define(常量名,常量值)
define("TOKEN", "weixin");
//实例化wechatCallbbackapiTest类
$wechatObj = new wechatCallbackapiTest();
//访问类中的valid方法,valid方法为验证开发模式接口
//验证完接口可以注释或删除掉
$wechatObj->valid();
//签名及接口验证
class wechatCallbackapiTest
{
//验证接口的方法
public function valid()
{
//从微信用户端获取一个随机字符赋予变量$echoStr
$echoStr = $_GET["echostr"];
//valid signature , option
//如果签名一致,输出变量$echoStr 完整验证配置接口的操作
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
//回复微信的关键
public function responseMsg()
{
//get post data, May be due to the different environments
//将用户端发送的数据保存到$postStr中
//由于,微信端发送的是XML的数据格式,使用$_POST无法解析
//故用$GLOBALS得到xml数据包信息
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
//extract post data
if (!empty($postStr)){//若用户端数据不为空,则
/* libxml_disable_entity_loader is to prevent XML eXternal Entity Injection,
the best way is to check the validity of xml by yourself */
//安全防御用的
//对于PHP,由于simplexml_load_string 函数的XML解析问题出现在libxml库上
libxml_disable_entity_loader(true);
//是PHP中一个解析XML的函数,参数SimpleXMLElement为新对象的类
//LIBXML_NOCDATA表示将CDATA设置为文本节点,CDATA标签中的文本XML不进行解析
//返回类 SimpleXMLElement 的一个对象,该对象的属性包含 XML 文档中的数据。如果失败,则返回 false。
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
//将微信用户端的用户名(OpenID)赋予变量$fromUsername
$fromUsername = $postObj->FromUserName;
//将你的微信公众号ID赋予变量$toUsername
$toUsername = $postObj->ToUserName;
//将用户微信发来的文本内容去掉空格后赋予变量$keyword
$keyword = trim($postObj->Content);
//将系统时间赋予变量$time
$time = time();
//构建XML格式的文本赋予变量$textTpl
//注意::XML中的格式为微信内容固定格式
$textTpl = "<xml>
<!--微信目标方,%s表示要转换成字符的数据类型
CDATA表示不转义
<![CDATA[XXXX]]>过滤,防止XML里面嵌套HTML标签导致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 ))//如果用户端发来的文本内容不为空,则
{
//回复文本信息类型为text型,即文本,变量类型为$msgType
$msgType = "text";
//回复信息内容,请尽情修改
$contentStr = "Welcome to wechat world!";
//将XML格式中的变量分别赋值
//sprintf()字符串格式化命令,主要功能是把格式化的数据写入某个字符串中
//将textTpl后面的参数信息写入这个xml字符串中
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
//输出回复信息,即发送微信
echo $resultStr;
}else{
//输入内容,不会发送到微信端,仅用于测试
echo "Input something...";
}
}else {//若用户端数据为空,回复为空,无意义,调试用
echo "";
exit;
}
}
//签名验证程序
//官方文档为加密/校验流程:
//将token、timestamp、nonce这三个参数进行字典序排序,
//将三个参数字符串接成一个字符串进行sha1加密
//开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
//建立私有方法验证签名
private function checkSignature()
{
// you must define TOKEN by yourself
if (!defined("TOKEN")) {
throw new Exception('TOKEN is not defined!');
}
//从用户端获取签名赋值变量$signature
$signature = $_GET["signature"];
//从用户端获取时间戳赋予变量$timestamp
$timestamp = $_GET["timestamp"];
//从用户端获取随机数赋予变量$nonce
$nonce = $_GET["nonce"];
//将常量TOKEN赋予$token
$token = TOKEN;
//建立数组变量
$tmpArr = array($token, $timestamp, $nonce);
// use SORT_STRING rule
sort($tmpArr, SORT_STRING);//新键名排序
$tmpStr = implode( $tmpArr );//字典排序
$tmpStr = sha1( $tmpStr );//sha1加密
if( $tmpStr == $signature ){//若$tmpStr与$signature同,则
return true;
}else{
return false;
}
}
}
?>