寫在前面
一個(gè)客戶需要做微信公眾平臺(tái)開發(fā)握侧,而自己以前沒有研究過蚯瞧,只做過訂閱號(hào),未涉及應(yīng)用開發(fā)品擎,于是簡(jiǎn)單了解了一下埋合,大概知道,只要會(huì)PHP+MYSQL萄传,加上XML甚颂、JSON、HTML等等秀菱,就能夠?qū)崿F(xiàn)了振诬。
所以我在這里記錄下自己的學(xué)習(xí)過程,給新學(xué)習(xí)的朋友一個(gè)參考衍菱,也給自己留個(gè)記錄赶么。
環(huán)境
1、需要一個(gè)微信公眾平臺(tái)賬號(hào)脊串,經(jīng)過認(rèn)證的辫呻,當(dāng)然認(rèn)證之前清钥,可以用測(cè)試賬號(hào)來做,點(diǎn)這里獲得測(cè)試賬號(hào):http://mp.weixin.qq.com/debug/cgi-bin/sandbox?t=sandbox/login
2放闺、需要一臺(tái)服務(wù)器祟昭,能夠部署你的WEB應(yīng)用,我使用的是阿里云服務(wù)器
3怖侦、需要一個(gè)域名(我現(xiàn)在還不確定是不是必須有篡悟,但沒有的話測(cè)試用不了),而且這個(gè)域名必須可以訪問(也就是備案了的)础钠,當(dāng)然如果你是國外的空間或服務(wù)器恰力,可以不備案直接解析。我因?yàn)橛蛎€沒備案完成旗吁,我在一些免費(fèi)的二級(jí)域名網(wǎng)站申請(qǐng)了一個(gè)解析到我服務(wù)器踩萎,速度很快,幾乎是瞬間就完成解析了很钓。我用的是這家的(http://dns.c3z.cn/control.php#)香府,不是廣告哦。
開始配置
我們以測(cè)試賬號(hào)為例進(jìn)行配置
關(guān)于服務(wù)器WEB應(yīng)用環(huán)境如何配置我不說了码倦,可以自己百度企孩。
關(guān)于各個(gè)參數(shù)怎么填寫,我且一個(gè)一個(gè)道來:
1袁稽、測(cè)試號(hào)信息:這里面的東西是隨機(jī)生成的勿璃,不需要我們來填寫,后邊用得到推汽。
2补疑、接口配置信息:這里需要我們自己填寫,在這之前要做一個(gè)準(zhǔn)備工作歹撒,把下面代碼復(fù)制后莲组,另存為wx_sample.php,
<?php
/**
* wechat php test
*/
//define your token
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
$wechatObj->valid();
class wechatCallbackapiTest
{
public function valid()
{
$echoStr = $_GET["echostr"];
echo $echoStr;
echo "<xml><ToUserName><![CDATA[toUser]]></ToUserName><FromUserName><![CDATA[fromUser]]></FromUserName><CreateTime>12345678</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[你好]]></Content></xml>";
//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"];
//extract post data
if (!empty($postStr)){
$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;
}
}
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;
}
}
}
?>
放到你的WEB目錄下暖夭,確鼻妈荆可以通過公網(wǎng)訪問。然后將URL設(shè)置如:http://123.123.123.123/wx_sample.php 即可迈着。
TOKEN項(xiàng)請(qǐng)?zhí)顚憽皐eixin”竭望,這個(gè)是可以后期修改的。
然后點(diǎn)擊提交裕菠。
提示配置成功咬清,表示成功了,但如果提示配置失敗,那么你要看一下代碼是不是我上面那一串枫振,因?yàn)槲⑿排渲脮r(shí)需要一個(gè)返回值,而如果你的代碼沒有返回值萤彩,微信會(huì)提示配置失敗粪滤,這時(shí)候你要加上才行。
我后來就遇到過這個(gè)問題雀扶,因?yàn)閾Q了一個(gè)目錄杖小,導(dǎo)致配置失敗,后來發(fā)現(xiàn)我只要在里邊加上一句:
$wechatObj = new wechatCallbackapiTest();
$wechatObj->valid();//新增加的這句
就OK了愚墓。
當(dāng)然后期你可以去掉予权。
JS接口安全域名,填寫我們前面申請(qǐng)的免費(fèi)二級(jí)域名(當(dāng)然你自己有備案好的域名更好啦)
添加測(cè)試號(hào)二維碼浪册,拿你的手機(jī)掃碼一下扫腺,關(guān)注即可,這樣你就可以在訂閱號(hào)列表中找到這個(gè)測(cè)試用的公眾號(hào)村象,通過給公眾號(hào)發(fā)送消息笆环,來測(cè)試返回的結(jié)果。
至此厚者,環(huán)境配置基本完畢躁劣。
Hello World!
下一步我們嘗試向公眾號(hào)發(fā)送任意字符库菲,返回一個(gè)"Hello world!"
其實(shí)账忘,說簡(jiǎn)單了,就像一個(gè)人抽了你一巴掌(用戶在訂閱號(hào)內(nèi)向你發(fā)送任意內(nèi)容)熙宇,你回頭踹了他一腳(你的程序回復(fù)一個(gè)“Hello World!”)
這個(gè)工作可以由剛才我們的那個(gè)php文件來完成鳖擒,他會(huì)首先接收來自微信的一個(gè)XML文件,里面包含了用戶發(fā)給你的內(nèi)容奇颠、類型等信息败去,你可以根據(jù)內(nèi)容,回復(fù)一個(gè)XML給微信烈拒,微信將XML解析后發(fā)給用戶圆裕。
相應(yīng)的源文件如下:
可以點(diǎn)擊這里下載:http://pan.baidu.com/s/1pKfkQEZ
<?php
/**
* wechat php test
*/
//define your token
define("TOKEN", "weixin");
$wechatObj = new wechatCallbackapiTest();
$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"];
//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!";
if($keyword == '1'){
$contentStr = "你輸入的是1";
}elseif($keyword == '1'){
$contentStr = "你輸入的是2";
}
$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
echo $resultStr;
}else{
echo "Input something...";
}
}else {
echo "";
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;
}
}
}
?>
測(cè)試
這時(shí)候我們可以開始測(cè)試了,向測(cè)試號(hào)發(fā)送任意字符荆几,將回復(fù)“Welcome to wechat world!"吓妆,發(fā)送數(shù)字1,回復(fù)"你輸入的是1"
OK吨铸,本節(jié)寫完了行拢。