微信公众平台开发(1)
目录
- 接入指南
- 实现简单的被动消息回复
1.接入指南
接入微信公众平台开发,开发者需要按照如下步骤完成:
- 填写服务器配置
- 验证服务器地址的有效性
- 依据接口文档实现业务逻辑
首先需要有自己的服务器,tracy这里用的是阿里云,下面开始接入公众号的介绍:
第一步:填写服务器配置
首先登陆公众号后台,在公众平台官网的开发-基本设置页面,勾选协议成为开发者,在左边最下面开发者中点击基本配置,进入配置页面:
点击“修改配置”按钮,填写服务器地址(URL)、Token和EncodingAESKey,这里的TOKEN在我们稍后编程中有用,可以任意填写,用作生成签名(该Token会和接口URL中包含的Token进行比对,从而验证安全性)
第二步:验证消息的确来自微信服务器
开发者提交信息后,微信服务器将发送GET请求到填写的服务器地址URL上,GET请求携带参数如下表所示:

开发者通过检验signature对请求进行校验(下面有校验方式)。若确认此次GET请求来自微信服务器,请原样返回echostr参数内容,则接入生效,成为开发者成功,否则接入失败。加密/校验流程如下:
- 1)将token、timestamp、nonce三个参数进行字典序排序
- 2)将三个参数字符串拼接成一个字符串进行sha1加密
- 3)开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
- 在公众号开发文档中可以查到验证token的php代码:
private function checkSignature()
{
$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.实现简单的被动消息回复
这里实现简单的天气预报功能,开发流程是:用户发送地点,如北京,服务器接受后访问天气API接口获取json再返回给微信服务器,用户再接收。话不多说,贴代码:
基本代码:
<?php
/**
* @author tracy
*/
//define your token
include "myweather.php";
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
if(isset($_GET["echostr"])){ #验证过token,成为开发者之后,可以直接$wechatObj->responseMsg();
$wechatObj->valid();
}else{
$wechatObj->responseMsg();
}
class wechatCallbackapiTest
{
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"];
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); #这里有从用户通过公众平台接收过来的数据,具体是什么类型的数据,开发者文档上写的很清楚,可以去上面查。
$fromUsername = $postObj->FromUserName;
$toUsername = $postObj->ToUserName;
$keyword = trim($postObj->Content);
$msgType = $postObj->MsgType;
$time = time();
switch( $msgType ){
case "text":
$url="http://wthrcdn.etouch.cn/weather_mini";
$city=array('city' => $keyword);
$arr=(array)json_decode(http($url,$city));
$content=implode(",", $arr);
$resultStr = $this->transmitText($postObj,$content);
echo $resultStr;
break;
case "event":
$resultStr = $this->handleEvent($postObj);
break;
default:
$resultStr = "Unknow msg type: ".$RX_TYPE;
break;
}
}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;
}
}
private function receiveText($object)
{
$keyword = trim($object->Content);
include("weather.php");
$content = getWeatherInfo($keyword);
$result = $this->transmitNews($object, $content);
return $result;
}
private function transmitText($object, $content)
{
$textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";
$result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time(), $content);
return $result;
}
private function transmitNews($object, $arr_item)
{
if(!is_array($arr_item))
return;
$itemTpl = " <item>
<Title><![CDATA[%s]]></Title>
<Description><![CDATA[%s]]></Description>
<PicUrl><![CDATA[%s]]></PicUrl>
<Url><![CDATA[%s]]></Url>
</item>
";
$item_str = "";
foreach ($arr_item as $item)
$item_str .= sprintf($itemTpl, $item['Title'], $item['Description'], $item['PicUrl'], $item['Url']);
$newsTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<Content><![CDATA[]]></Content>
<ArticleCount>%s</ArticleCount>
<Articles>
$item_str</Articles>
</xml>";
$result = sprintf($newsTpl, $object->FromUserName, $object->ToUserName, time(), count($arr_item));
return $result;
}
}
?>
天气查询代码myweather.php
<?php
header ( "Content-type: text/html; charset=utf-8" );
function http($url,$params,$method='GET',$header=array(),$multi=false){
$opts=array(
CURLOPT_TIMEOUT => 30,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER =>$header
);
switch (strtoupper($method)) {
case 'GET':
$opts[CURLOPT_URL]=$url.'?'.http_build_query($params);
break;
case 'POST':
$opts[CURLOPT_URL]=$url;
$opts[CURLOPT_POST]=1;
$opts[CURLOPT_POSTFIELDS]=$params;
break;
default:
throw new Exception("Error Processing Request", 1);
}
$ch=curl_init();
//HTTP请求头中"Accept-Encoding: "的值。 这使得能够解码响应的内容。 支持的编码有"identity","deflate"和"gzip"。如果为空字符串"",会发送所有支持的编码类型
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt_array($ch, $opts);
$data=curl_exec($ch);
$error=curl_error($ch);
curl_close($ch);
if ($error) {
throw new Exception("Error Processing Request", 1);
}
return json_encode($data);
}
//get提交
$url="http://wthrcdn.etouch.cn/weather_mini";
$city=array('city' => '北京');
/* echo http_build_query($city);*/
echo http($url,$city);
?>