微信開發最近很火,本文主要和大家分享PH實現用微信遠端遙控伺服器功能實例,大致的功能還是有的,不過是不全,很多地方我沒有進行處理。不過對於純文字方式的交流,已經沒有問題啦。
下面大致的講講微信公眾號的原理吧。可能我理解的有些不到位,如果有些許不當,歡迎批評指教。
客戶端發送給微信平台請求,微信平台將請求轉發給私服,交給程式處理之後,取得到私服的處理結果,然後回饋給客戶端。
當然,這其中起到核心作用的自然是「微信公眾平台」啦。相當於提供了一個舞台,一個能讓各位能人異士展現各自的特色的平台。其實,不只微信如此,阿里同樣是這樣,如此各大電商才能一展手腳不是。
開啟設定
這第一步,就是先申請一個微信開發者帳號,個人的話選擇訂閱號就夠了。網路上相關的資料很多,也很詳細,我就不多說了。咱們直奔主題好了。
先登陸開發者帳號成功後,開啟伺服器端的設定即可,如下圖
開啟完成,依照自己伺服器的狀況進行設定即可。
URL就是你的私服用於處理請求資料的位址
#TOKEN就是一個令牌,隨便設定。不過記得待會自己的程式碼上會用到。
至於金鑰嘛,沒什麼較大的作用,暫且可以先不用管。
按需設定
設定完,就可以啟用了。這就好比家裡的電線全部裝潢好了,現在要使用,按下開關一樣。如下圖
啟用伺服器設定
伺服器環境
關於伺服器這塊,官網上講解的也是很詳細的啦。
https://mp.weixin.qq.com/wiki
我們也可以下載官方的demo來模擬。
官方樣本
程式碼也很簡單。基本上學過了PHP基本語法的都能夠看得懂。
<?php /** * wechat php test */ //define your token define("TOKEN", "weixin"); $wechatObj = new wechatCallbackapiTest(); $wechatObj->valid(); 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></tousername> <fromusername></fromusername> <createtime>%s</createtime> <msgtype></msgtype> <content></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() { // 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; } } } ?>
核心思路,無非檢驗一下簽名,處理一下請求,回饋一下結果罷了。
這裡我不得不想說的就是,我覺得騰訊其實可以將那些個模板什麼的去掉,直接暴露出黑盒模式,這樣的話安全性會更高一點。很多時候,權限放的越開,效果可能越差。
核心類別
接下來就是我自己的處理邏輯了,參考官方文件。微信公眾好上有6大接收接口,三大回覆接口。依據MsgType即可判定。
介面詳情
驗證
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; } }
驗證方法核心就是依據咱們之前網頁上設定的TOKEN來運作的,所以程式碼上會用得到。
回覆
回覆的程式碼需要依據客戶端發送的資料的類型來區分對待,類型這塊微信平台會將資料打包好封裝起來,我們住需要呼叫內部的MsgType進行處理即可。
拓展
拓展部分,是我自己異想天開往上加的。
添加機器人
調用一個機器人接口,來代替自己發送回复,技能讓用戶得到一個良好的用戶體驗,還能愉悅大眾,何樂而不為?
我這邊測試了兩個接口,一個是curl模式,一個是file_get_contents模式,都蠻好用的囉。
<?php /** * 图灵 机器人接口 * * 使用curl来进行浏览器模拟并抓取数据 */ function turing($requestStr) { // 图灵机器人接口 $url = "http://www.tuling123.com/openapi/api"; // 用于POST请求的数据 $data = array( 'key'=>"哈哈,这个key还是得你自己去申请的啦", 'info'=>$requestStr, ); // 构造curl下载器 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $responseStr = curl_exec($ch); curl_close($ch); return $responseStr; } /** * 调用另外的接口 * @param unknown $req * @return mixed */ function test($req){ $url = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=".$req; $result = file_get_contents($url); $result = json_decode($result, true); return $result['content']; } $req = 'hello'; $res = test($req); echo $res;
指令模式
手機相對於電腦一個很大的優點就是便攜,我們雖然不能隨時隨地攜帶電腦,但是卻能使用手機來代替。很多時候對伺服器的管理需要的PHP實作用微信遠端遙控伺服器功能實例很簡單,但是遠端登入的時候也不方便。這時候就用微信來幫忙傳話也是不錯的啦。
我平常喜歡使用Python寫一些腳本,什麼獲取本地IP,聊天,查看內存,網速啥的,可謂是應有盡有。這下也終於能有用武之地了。利用微信的關鍵字匹配,就可以簡單的讓微信公眾號當一個小小傳話員啦。
這裡給個思路,具體實作起來也比較簡單,當做是文字來處理即可。
完整程式碼
下面貼出我伺服器上的完整程式碼,有些私密的地方我做了些更改,屆時按照自己的情況進行修改即可。
valid(); // 调用回复信息方法 $wechatObj->responseMsg (); // 微信消息处理核心类 class wechatCallbackapiTest { public function valid() { $echoStr = $_GET ["echostr"]; // valid signature , option if ($this->checkSignature ()) { echo $echoStr; exit (); } else { echo "验证失败!"; } } public function responseMsg() { // get post data, May be due to the different environments // 类似$_POST但是可以接受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 */ // 不解析外部数据,防止xxml漏洞 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 (); /* * 微信客户端发送信息的时候会附带一些参数,详见官方文档。所以要根据不同的类型,来分别做相关的处理。 * 于是MsgType 就充当这样的一个区分的标记 */ $msgType = $postObj->MsgType; /* * 当有用户关注后者退订的时候,会触发相应的事件。所以再来个event事件的监听更为友好。 * $event = $postObj->Event. * 具体的参数信息,官网上很详细。 */ $event = $postObj->Event; switch ($msgType) { // 文本消息 处理部分 case "text" : if (! empty ( $keyword )) { // 在此处进行对关键字的匹配就可以实现:针对不同关键字组装的相应数据 if($keyword=='PHP實作用微信遠端遙控伺服器功能實例' || $keyword == "music") { $msgType = 'music'; $musictitle = "The Mountain"; $musicdescription = "夏日舒心清凉歌曲"; $musicurl = "http://101.200.58.242/wx/themaintain.mp3"; $hqmusicurl = "http://101.200.58.242/wx/themaintain.mp3"; musicMessageHandle($fromUsername, $toUsername, $time, $msgType, $musictitle, $musicdescription, $musicurl, $hqmusicurl); }elseif($keyword == '1'){ $msgType = 'text'; $contentStr = "人生得意须尽欢,莫使金樽空对月!"; textMessageHandle($fromUsername, $toUsername, $time, $msgType, $contentStr); }elseif($keyword == 'PHP實作用微信遠端遙控伺服器功能實例模式'){ $msgType = 'text'; $contentStr = "进入PHP實作用微信遠端遙控伺服器功能實例模式,开始对服务器进行管理!\n接下来将依据您输入的PHP實作用微信遠端遙控伺服器功能實例对服务器进行管理!"; textMessageHandle($fromUsername, $toUsername, $time, $msgType, $contentStr); }else { // 直接调用 机器人接口,与用户进行交流 $msgType = "text"; $contentStr = turing($keyword)!=""?turing($keyword):"这里是微信 纯文本测试数据!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } } else { echo "您得输入点数据,我才能回复不是!"; } break; // 接收图片信息 case "image" : if (! empty ( $keyword )) { // $msgType = "image"; $contentStr = "您发送的图片看起来还真不错!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } else { echo "服务器没能收到您发送的图片!"; } break; // 接收语音信息 case "voice" : if (! empty ( $keyword )) { // $msgType = "voice"; $contentStr = "您发送的语音听起来还真不错!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } else { echo "服务器没能收到您发送的语音!"; } break; // 接收视频信息 case "video" : if (! empty ( $keyword )) { // $msgType = "video"; $contentStr = "您发送的视频看起来还真不错!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } else { echo "服务器没能收到您发送的视频!"; } break; // 接收视频信息 case "shortvideo" : if (! empty ( $keyword )) { // $msgType = "shortvideo"; $contentStr = "您发送的小视频看起来还真不错!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } else { echo "服务器没能收到您发送的小视频!"; } break; // 接收位置信息 case "location" : if (! empty ( $keyword )) { // $msgType = "location"; $contentStr = "您发送的位置已被接收!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } else { echo "服务器没能收到您发送的位置!"; } break; // 接收视频信息 case "link" : if (! empty ( $keyword )) { // $msgType = "link"; $contentStr = "您发送的链接看起来还真不错!"; textMessageHandle ( $fromUsername, $toUsername, $time, $msgType, $contentStr ); } else { echo "服务器没能收到您发送的链接!"; } break; // 对事件进行侦听 case "event": switch ($event) { case "subscribe": // 发送一些消息! $msgType = 'text'; $contentStr = "终于等到你!"; textMessageHandle($fromUsername, $toUsername, $time, $msgType, $contentStr); break; } break; default : break; } } 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; } } } /** * 定义为心中想难关的六个接口的数据发送格式模板 */ function textMessageHandle($fromUsername, $toUsername, $time, $msgType, $contentStr) { $textTpl = ""; $resultStr = sprintf ( $textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr ); echo $resultStr; } function imageMessageHandle($fromUsername, $toUsername, $time, $msgType, $contentStr) { $imageTpl = " %s 0 "; $resultStr = sprintf ( $textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr ); echo $resultStr; } function musicMessageHandle($fromUsername, $toUsername, $time, $msgType, $musictitle, $musicDescription, $musicurl, $hqmusicurl) { $musicTpl = " %s 1234567890123456 "; $resultStr = sprintf($musicTpl, $fromUsername, $toUsername, $time, $msgType, $musictitle, $musicDescription, $musicurl, $hqmusicurl); echo $resultStr; } /** * 图灵 机器人接口 * * 使用curl来进行浏览器模拟并抓取数据 */ function turing($requestStr) { /* // 图灵机器人接口 $url = "http://www.tuling123.com/openapi/api"; // 用于POST请求的数据 $data = array( "key"=>"您在图灵机器人官网上申请的key", "info"=>$requestStr ); // 构造curl下载器 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $data); $requestStr = curl_exec($ch); curl_close($ch); return responseStr; */ $url = "http://api.qingyunke.com/api.php?key=free&appid=0&msg=".$requestStr; $result = file_get_contents($url); $result = json_decode($result, true); return $result['content']; } ?> %s
總結
最後來回顧一下,這次試驗用到了哪些知識點。
PHP的物件導向方法程式設計簡單實作。
介面處理的兩種方式
微信公眾號後台私服的接入,處理,回饋。
前後端的交互,以及聊天機器人的應用。
其實,這些程式碼跟我一開始的設想還是差別挺大的,原本是想實現一個“遙控器”,晚上想睡覺之前,用微信發一條PHP實作用微信遠端遙控伺服器功能實例“打開電熱毯”,半個小時後,電視看完了,去睡覺的時候發現被窩很暖和,是的,只要加上點硬件,這很容易實現啦再者冰箱了,電視了統統可以完成,那樣估計就診的是「智慧家庭」了吧。
相關推薦:
#以上是PHP實作用微信遠端遙控伺服器功能實例的詳細內容。更多資訊請關注PHP中文網其他相關文章!