PHP开发之用微信远程遥控服务器(2)

这里我不得不想说的就是,我觉得腾讯其实可以将那些个模板什么的去掉,直接暴露出黑盒模式,这样的话安全性会更高一点。很多时候,权限放的越开,效果可能越差。

核心类

接下来就是我自己的处理逻辑了,参照官方文档。微信公众好上有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;

命令模式

手机相对于电脑一个很大的优点就是便携,我们虽然不能随时随地携带电脑,但是却能使用手机来代替。很多时候对服务器的管理需要的命令很简单,但是远程登录的时候也不方便。这个时候就用微信来帮忙传话也是不错的啦。

我平时喜欢使用Python写一些脚本,什么获取本地IP,聊天,查看内存,网速啥的,可谓是应有尽有。这下也终于能有用武之地了。利用微信的关键字匹配,就可以简单的让微信公众号当一个小小传话员啦。

这里给个思路,具体实现起来也比较简单,当做是文本来处理即可。

完整代码

下面贴出我服务器上的完整代码,有些私密的地方我做了些更改,届时按照自己的情况进行修改即可。

<?php /** * wechat php test */ // define your token define ( "TOKEN", "您的TOKEN" ); $wechatObj = new wechatCallbackapiTest (); // $wechatObj->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=='音乐' || $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 == '命令模式'){ $msgType = 'text'; $contentStr = "进入命令模式,开始对服务器进行管理!\n接下来将依据您输入的命令对服务器进行管理!"; 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 = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <FuncFlag>0</FuncFlag> </xml>"; $resultStr = sprintf ( $textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr ); echo $resultStr; } function imageMessageHandle($fromUsername, $toUsername, $time, $msgType, $contentStr) { $imageTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Content><![CDATA[%s]]></Content> <PicUrl><![CDATA[this is a url]]></PicUrl> <MediaId><![CDATA[media_id]]></MediaId> <MsgId>1234567890123456</MsgId> </xml>"; $resultStr = sprintf ( $textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr ); echo $resultStr; } function musicMessageHandle($fromUsername, $toUsername, $time, $msgType, $musictitle, $musicDescription, $musicurl, $hqmusicurl) { $musicTpl = "<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> <Music> <Title><![CDATA[%s]]></Title> <Description><![CDATA[%s]]></Description> <MusicUrl><![CDATA[%s]]></MusicUrl> <HQMusicUrl><![CDATA[%s]]></HQMusicUrl> </Music> </xml>"; $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']; } ?>

总结

最后来回顾一下,本次试验用到了哪些知识点。

PHP的面向对象方法编程简单实现。

接口处理的两种方式

微信公众号后台私服的接入,处理,反馈。

前后端的交互,以及聊天机器人的应用。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/ecc592c538fd76a82d1481fb754678ae.html