程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 網頁編程 >> PHP編程 >> PHP綜合 >> php微信公眾平台交互與接口詳解

php微信公眾平台交互與接口詳解

編輯:PHP綜合

本文分為三大部分為大家進行介紹,具體內容如下

1、微信用戶、微信服務器和後台服務器的交互

例:微信用戶向公眾號發送一條文本消息,這條消息會首先傳給微信服務器,微信服務器處理這條信息並將其以xml數據格式傳遞給後台服務器,後台服務器接受到數據後會對數據進行處理,再響應數據以xml數據格式傳遞給微信服務器,微信服務器再響應到用戶微信界面。
微信用戶與微信後台服務器之間的交互過程就是數據傳遞過程,只不過需要需要通過微信服務器這個中轉站。

那麼微信服務器這個中轉站到底有什麼用?
對xml數據進行加工包裝後展現在手機屏幕上。我們接受的圖文消息,如下:

單圖文:

多圖文

你會發現微信上幾乎所有的圖文都是這種格式,板式、大小都是一樣,這就是經過微信服務器包裝後的結果。

2、交互的數據類型

微信用戶可以發送的數據類型
1、文本型(text)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[%s]]></Content>
</xml>";

2、語音(voice)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<Format><![CDATA[amr]]></Format>
<MsgId>5836982871638042400</MsgId>
<MediaId><![CDATA[PGKsO3LAgbVTsFYO7FGu51KUYa07D0C_Nozz2fn1z6VYtHOsF59PTFl0vagGxkVH]]></MediaId>
<Recognition><![CDATA[]]></Recognition>//recognition表示語音識別的結果
</xml>

3、圖片( img)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<PicUrl><![CDATA[http://mmbiz.qpic.cn/mmbiz/L4qjYtOibummHn90t1mnaibYiaR8ljyicF3MW7XX3BLp1qZgUb7CtZ0D]]></PicUrl>
<MsgId>5836982871638042400</MsgId>
<MediaId><![CDATA[PGKsO3LAgbVTsFYO7FGu51KUYa07D0C_Nozz2fn1z6VYtHOsF59PTFl0vagGxkVH]]></MediaId>
</xml>

每一條消息傳給微信服務器後都會被標記一個MsgId,上傳的圖片、視頻、語音等也會被標記一個mediaId。

4、視頻(video)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[vedio]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<MediaId><![CDATA[PGKsO3LAgbVTsFYO7FGu51KUYa07D0C_Nozz2fn1z6VYtHOsF59PTFl0vagGxkVH]]></MediaId>
<ThumbMediaId><![CDATA[mxUJ5gcCeesJwx2T9qsk62YzI
clCP_HnRdfTQcojlPeT2G9Q3d22UkSLyBFLZ01J]]></ThumbMediald>;//視頻靜止時顯示那張圖片地址
</xml>

5、地理位置消息(location)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[location]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<Location_X>22.539968</Location_X>
<Location_Y>113.954980</Location_Y>
<Scale>16</Scale>
<Label><![CDATA[中國廣東省深圳市南山區深南大道9001號 
郵政編碼: 518053]]></Label>
</xml>

6、鏈接消息(link)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[link]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<Title><![CDATA[微信公眾平台開發者的江湖]]></Title>
<Description><![CDATA[陳坤的微信公眾號這段時間大火,大家...]]></Description>
<Url><![CDATA[http://www.cnblogs.com/txw1958/]]></Url>
<MsgId>5839907284805129867</MsgId>
</xml>

後台服務器響應的消息類型
1、文本型(text)
2、語音(voice)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<Voice>
<MediaId><![CDATA[PGKsO3LAgbVTsFYO7FGu51KUYa07D0C_Nozz2fn1z6VYtHOsF59PTFl0vagGxkVH]]></MediaId>
</Voice>
</xml>

3、圖片( img)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<Image>
<MediaId><![CDATA[PGKsO3LAgbVTsFYO7FGu51KUYa07D0C_Nozz2fn1z6VYtHOsF59PTFl0vagGxkVH]]></MediaId>
</Image>
</xml>

4、視頻(video)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[vedio]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<video>
<MediaId><![CDATA[PGKsO3LAgbVTsFYO7FGu51KUYa07D0C_Nozz2fn1z6VYtHOsF59PTFl0vagGxkVH]]></MediaId>
<ThumbMediaId><![CDATA[mxUJ5gcCeesJwx2T9qsk62YzI
clCP_HnRdfTQcojlPeT2G9Q3d22UkSLyBFLZ01J]]></ThumbMediald>;//視頻靜止時顯示那張圖片地址
</video>
</xml>

5、音樂(music)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<Music>
<Title><![CDATA[最炫民族風]]></Title>
<Description><![CDATA[鳳凰傳奇]]></Description>
<MusicUrl><![CDATA[http://zj189.cn/zj/download/music/zxmzf.mp3]]></MusicUrl>
<HQMusicUrl><![CDATA[http://zj189.cn/zj/dodownload/music/zxmzf.mp3]]></HQMusicUrl>
</Music>
</xml>

6、圖文(news)

<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[news]]></MsgType>
<MsgId>5836982871638042400</MsgId>
<Content><![CDATA[]]></Content>
<ArticleCount>%s</ArticleCount>
<Articles>
<item>
<Title><![CDATA[ 【深圳】實況 溫度:6℃ 濕度:62﹪ 風速:東北風2級]]></Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/banner.jpg]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
<item>
<Title><![CDATA[ 【深圳】實況 溫度:6℃ 濕度:62﹪ 風速:東北風2級]]></Title>
<Description><![CDATA[]]></Description>
<PicUrl><![CDATA[http://www.doucube.com/weixin/weather/icon/banner.jpg]]></PicUrl>
<Url><![CDATA[]]></Url>
</item>
</Articles>
</xml>

上面代碼在數據填寫方面只做參照。以上代碼在需要的時候調用即可,這裡只是為大家展現以下數據格式。
CDATA是一個標記,被其標記的文本數據中不會被xml解析器進行解析。一個 CDATA 部件以"

ToUserName  接收方帳號
FromUserName  發送方帳號
CreateTime 發送事件
MsgType  數據類型
Content   文本內容
ArticleCount  圖文數量
MsgId  數據id
MediaId  媒介id
Title  標題
Description  描述
MusicUrl   音樂連接地址
HQMusicUrl  高品質音樂連接地址

2、具體的交互步驟即代碼

在上一章圖2中,我們為測試號定義了url和token。url就是與微信服務器進行通信的後台服務器地址,而token一個相當於一個令牌。微信服務器與後台服務器進行通信時會出示該令牌,如果後台服務器發現微信服務器與自己攜帶的令牌相同才會進行通信,不相同則拒絕通信 。這個過程叫做token驗證(這個令牌不是token的值)。
上面比較形象的說話,下面我通過代碼來解釋
例如:url為http://weixinceshi111111.applinzi.com/index2.php
token:weixin
index2.php代碼

<?php
//
// 響應用戶消息
// 微信公眾賬號響應給用戶的不同消息類型
//微信服務器要和後台服務器進行通信首先要進行token驗證,微信會通過get方式發送signature(微信加密簽名)、nonce(隨機數)、timestamp(時間戳)、echostr(隨機字符串)。後台服務器獲取之後會將timestamp、nonce與自身定義的TOKEN按照一定的順序拼接成字符串,通過shal加密後獲得的結果與signature進行對比,如果相同則把echostr返回給微信服務器。 表示驗證成功。
header("content-type:text;charset=utf8");
define("TOKEN", "weixin");
//token驗證是通過get傳輸數據,微信用戶發送的數據通過post方式發送。先進行get請求,再進行post請求。
$wechatObj = new wechatCallbackapiTest();
//判斷是get請求還是post請求。$_GET['echostr']如果存在,表示是進行token驗證的get請求。反之是傳輸數據的post請求。
if (!isset($_GET['echostr'])) {
 $wechatObj->responseMsg();//響應數據
}else{
 $wechatObj->valid();//響應
}

class wechatCallbackapiTest
{
 public function valid()
 {
 $echoStr = $_GET["echostr"];
 if($this->checkSignature()){
 echo $echoStr;
 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;
 }
 }

 public function responseMsg()
 {
 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];//獲取發送過來的數據。
 if (!empty($postStr)){
 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', );//把xml字符串載入到一個SimpleXMLelement對象中。simplexml_load_string()是一種xml解析器。
 $RX_TYPE = trim($postObj->MsgType);//trim去掉字符串兩端kongge。

 //用戶發送的消息類型判斷
 switch ($RX_TYPE)
 {
 case "text":
  $result = $this->receiveText($postObj);
  break;
 case "image":
  $result = $this->receiveImage($postObj);
  break;
 case "voice":
  $result = $this->receiveVoice($postObj);
  break;
 case "video":
  $result = $this->receiveVideo($postObj);
  break;
 default:
  $result = "unknow msg type: ".$RX_TYPE;
  break;
 }
 echo $result;
 }else {
 echo "";
 exit;
 }
 }

 private function receiveText($object)
 {
 $keyword = trim($object->Content);

 if($keyword == "文本"){
 //回復文本消息
 $content = "這是個文本消息";
 $result = $this->transmitText($object, $content);
 }
 else if($keyword == "圖文" || $keyword == "單圖文"){
 //回復單圖文消息
 $content = array();
 $content[] = array("Title"=>"單圖文標題", 
  "Description"=>"單圖文內容", 
  "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", 
  "Url" =>"http://m.cnblogs.com/?u=txw1958");
 $result = $this->transmitNews($object, $content);
 }
 else if($keyword == "多圖文"){
 //回復多圖文消息
 $content = array();
 $content[] = array("Title"=>"多圖文1標題", "Description"=>"", "PicUrl"=>"http://discuz.comli.com/weixin/weather/icon/cartoon.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
 $content[] = array("Title"=>"多圖文2標題", "Description"=>"", "PicUrl"=>"http://d.hiphotos.bdimg.com/wisegame/pic/item/f3529822720e0cf3ac9f1ada0846f21fbe09aaa3.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
 $content[] = array("Title"=>"多圖文3標題", "Description"=>"", "PicUrl"=>"http://g.hiphotos.bdimg.com/wisegame/pic/item/18cb0a46f21fbe090d338acc6a600c338644adfd.jpg", "Url" =>"http://m.cnblogs.com/?u=txw1958");
 $result = $this->transmitNews($object, $content);

 }
 else if($keyword == "音樂"){
 //回復音樂消息
 $content = array("Title"=>"最炫民族風", 
 "Description"=>"歌手:鳳凰傳奇", 
 "MusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3",
 "HQMusicUrl"=>"http://121.199.4.61/music/zxmzf.mp3");
 $result = $this->transmitMusic($object, $content);
 }

 return $result;
 }

 private function receiveImage($object)
 {
 //回復圖片消息 
 $content = array("MediaId"=>$object->MediaId);
 $result = $this->transmitImage($object, $content);;
 return $result;
 }

 private function receiveVoice($object)
 {
 //回復語音消息 
 $content = array("MediaId"=>$object->MediaId);
 $result = $this->transmitVoice($object, $content);;
 return $result;
 }

 private function receiveVideo($object)
 {
 //回復視頻消息 
 $content = array("MediaId"=>$object->MediaId, "ThumbMediaId"=>$object->ThumbMediaId, "Title"=>"", "Description"=>"");
 $result = $this->transmitVideo($object, $content);;
 return $result;
 } 

 /*
 * 回復文本消息,將要回復的xml消息進行包裝。
 */
 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);//sprintf()這個函數的作用還是比較有意思的,可以搜索看看。
 return $result;
 }

 /*
 * 回復圖片消息
 */
 private function transmitImage($object, $imageArray)
 {
 $itemTpl = "<Image>
 <MediaId><![CDATA[%s]]></MediaId>
</Image>";

 $item_str = sprintf($itemTpl, $imageArray['MediaId']);

 $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[image]]></MsgType>
$item_str
</xml>";

 $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
 return $result;
 }

 /*
 * 回復語音消息
 */
 private function transmitVoice($object, $voiceArray)
 {
 $itemTpl = "<Voice>
 <MediaId><![CDATA[%s]]></MediaId>
</Voice>";

 $item_str = sprintf($itemTpl, $voiceArray['MediaId']);

 $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[voice]]></MsgType>
$item_str
</xml>";

 $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
 return $result;
 }

 /*
 * 回復視頻消息
 */
 private function transmitVideo($object, $videoArray)
 {
 $itemTpl = "<Video>
 <MediaId><![CDATA[%s]]></MediaId>
 <ThumbMediaId><![CDATA[%s]]></ThumbMediaId>
 <Title><![CDATA[%s]]></Title>
 <Description><![CDATA[%s]]></Description>
</Video>";

 $item_str = sprintf($itemTpl, $videoArray['MediaId'], $videoArray['ThumbMediaId'], $videoArray['Title'], $videoArray['Description']);

 $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[video]]></MsgType>
$item_str
</xml>";

 $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
 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;
 }

 /*
 * 回復音樂消息
 */
 private function transmitMusic($object, $musicArray)
 {
 $itemTpl = "<Music>
 <Title><![CDATA[%s]]></Title>
 <Description><![CDATA[%s]]></Description>
 <MusicUrl><![CDATA[%s]]></MusicUrl>
 <HQMusicUrl><![CDATA[%s]]></HQMusicUrl>
</Music>";

 $item_str = sprintf($itemTpl, $musicArray['Title'], $musicArray['Description'], $musicArray['MusicUrl'], $musicArray['HQMusicUrl']);

 $textTpl = "<xml>
<ToUserName><![CDATA[%s]]></ToUserName>
<FromUserName><![CDATA[%s]]></FromUserName>
<CreateTime>%s</CreateTime>
<MsgType><![CDATA[music]]></MsgType>
$item_str
</xml>";

 $result = sprintf($textTpl, $object->FromUserName, $object->ToUserName, time());
 return $result;
 }
}
?>

3.接口

3.1 接口是什麼

接口就相當於一個工具,具備特定的功能。比如你在建造房子的時候需要在牆上鑽孔,你就會使用鑽機工具來鑽孔。從調來工具到鑽孔完成,你要完成插電、校准、鑽孔等一系列步驟,最終實現你的目標。鑽機就是我們的接口,插電、校准、鑽孔就是我們調用工具完成目的步驟。

微信的創建菜單接口舉例。

調用接口的步驟:
1、獲得微信菜單接口的連接地址,通過curl函數與這個接口建立對話。
2、把創建菜單數據發送給這個接口。
接口調用完成,這個接口會自動把這些數據進行處理並在微信公眾好頁面生成菜單。

微信接口的調用方式請看下一章:微信公眾平台開發(三):微信高級接口的調用。

以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved