1、准备
首先你得有一个微信公众号,一个服务器
没有服务器可以用新浪云服务 https://sae.sina.com.cn
选择 云应用SAE -> 添加新应用
代码上传:SAE支持Git、SVN、代码打包上传三种提交方式
例如:git方式:
在你应用的git代码目录里,添加一个新的git远程仓库 sae
$ git remote add sae https://git.sinacloud.com/appname
编辑代码并将代码部署到 sae
的版本1。
$ git add .
$ git commit -am “bababa”
$ git push sae master:1
代码上传后,自动生成 http://1.appname.applinzi.com/
这就是第一个应用的服务地址
2、公众号配置和初始
开发手册:
https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421135319&token=&lang=zh_CN
初始代码:
三个必要函数:
public function valid()
private function checkSignature()
public function responseMsg()
参数配置
http://mp.weixin.qq.com/mpres/htmledition/res/wx_sample.20140819.zipwx_sample.php
define("TOKEN", "weixin");//可将‘weixin'改为自定义的token
$wechatObj = new wechatCallbackapiTest();//实例化一个微信接口类,包含了验证函数、消息和事件处理函数
$wechatObj->valid();//验证请求是否来源于微信
使用新浪sae时,需要在代码前加上:header('Content-type:text');
不加的话可能会出现“验证token失败”的错误
token验证函数
微信发送过来的验证token请求
class wechatCallbackapiTest
{
public function valid()//验证合法性函数
{
$echoStr = $_GET["echostr"];
//valid signature , option
if($this->checkSignature()){
echo $echoStr;
exit;
}
}
private function checkSignature()//签名验证函数
{
// you must define TOKEN by yourself
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);
// use SORT_STRING rule
sort($tmpArr, SORT_STRING);
$tmpStr = implode( $tmpArr );
$tmpStr = sha1( $tmpStr );
if( $tmpStr == $signature ){
return true;
}else{
return false;
}
}
public function responseMsg()
{
//处理消息
}
}
将token、timestamp、nonce三个参数作为字符串进行排序,
将三个参数字符串拼接成一个字符串进行sha1加密,
开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
公众号配置:
开发->基本配置->修改配置->启用
3、功能开发
消息处理函数 public function responseMsg()
public function responseMsg()
{
$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 */
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 = "Welcome to wechat world!";
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
exit;
}
}
微信发送过来,和返回的消息都是xml$postStr:
接收到的消息
post过来的数据不是PHP能够识别的,用 $GLOBALS[‘HTTP_RAW_POST_DATA’]来接收$fromUsername:
发送方帐号$toUsername:
开发者微信号$keyword:
用户发送给该公众号的微信消息
$msgType:
- text、image、voice、video、shortvideo、location、link :接收的消息类型/发送的消息类型
- event:接收到的为事件消息(关注/取关,扫描带二维码、上报地理位置、自定义菜单)
手册:https://mp.weixin.qq.com/wiki?t=resource/res_main&id=mp1421140454&token=&lang=zh_CN
在实际代码中,都是先判断消息类型,然后选择该进入哪一个处理函数
简化后的函数 responseMsg()
public function responseMsg()
{
$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
if (!empty($postStr)){
$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
$RX_TYPE = trim($postObj->MsgType);
switch ($RX_TYPE)
{
case "text":
$resultStr = $this->receiveText($postObj);
break;
case "event":
$resultStr = $this->receiveEvent($postObj);
break;
}
echo $resultStr;
}else {
echo "";
exit;
}
}
private function receiveText($object){...}
private function receiveEvent($object){...}