<kbd id='woaibaidu'></kbd><address id='woaibaidu'><style id='woaibaidu'></style></address><button id='woaibaidu'></button>

          当前位置:主页 > 网络编程 > PHP编程 >
            PHP开发之用微信远程遥控服务器
            2018-01-29 22:02 发布 次浏览

           摘要

          微信大众好的开发很火,小顺序更火。因而也凑个繁华,实验了1把。

          大致的功用照旧有的,不外是不全,许多中央我没有停止处置。不外关于纯文本方式的交换,曾经没有成绩啦。

          命令

          音乐

          情况搭建

          上面大致的讲讲微信大众号的原理吧。能够我了解的有些不到位,假如有些许不妥,欢送批判指教。

          客户端发送给微信平台恳求,微信平台将恳求转发给私服,交给顺序处置以后,获得到私服的处置后果,然后反应给客户端。

          固然,这其中起到中心作用的自然是“微信大众平台”啦。相当于提供了1个舞台,1个能让列位能人异士展示出各自的特征的平台。其实,不只微信如此,阿里异样是这样,如此各大电商才干1展手脚不是。

          开启设置

          这第1步,就是先请求1个微信开发者账号,团体的话选择定阅号就足够了。网上相干的材料许多,也很详细,我就不多说了。我们直奔主题好了。

          首先登陆开发者账号乐成后,开启效劳器真个设置便可,以下图

          开启配置

          开启完成,依据本人效劳器的状况停止1下设置便可。

          • URL就是你的私服用于处置恳求数据的地址
          • TOKEN就是1个令牌,随意设置。不外记着待会本人的代码上会用到。
          • 至于密钥嘛,没甚么较大的作用,暂且可以先不必管。

          按需设置

          按需设置

          设置完,就能够启用了。这就好比家里的电线全部装修睦了,如今要运用,按下开关1样。以下图

          启用服务器配置

          启用效劳器设置

          效劳器情况

          关于效劳器这块,官网上解说的也是很详细的啦。

          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><![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()
           {
           // 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;
           }
           }
          }
          ?>

          中心思绪,不过磨练1下签名,处置1下恳求,反应1下后果而已。

          这里我不能不想说的就是,我以为腾讯其实可以将那些个模板甚么的去掉,直接袒露出黑盒形式,这样的话平安性会更高1点。许多时分,权限放的越开,效果能够越差。

          中心类

          接上去就是我本人的处置逻辑了,参照官方文档。微信大众好上有6大接纳接口,3大回复接口。根据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停止处置便可。

          拓展

          拓展局部,是我本人想入非非往上加的。

          添加机械人

          挪用1个机械人接口,来替代本人发送回复,技艺让用户失掉1个良好的用户体验,还能愉悦群众,何乐而不为?

          我这边测试了两个接口,1个是curl形式,1个是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;

          下令形式

          手机绝对于电脑1个很大的优点就是便携,我们虽然不能随时随地携带电脑,可是却能运用手机来替代。许多时分对效劳器的治理需求的下令很复杂,可是近程登录的时分也不利便。这个时分就用微信来帮助传话也是不错的啦。

          我平常喜欢运用Python写1些剧本,甚么获得当地IP,谈天,检查内存,网速啥的,可谓是应有尽有。这下也终究能有用武之地了。应用微信的要害字婚配,就能够复杂的让微信大众号当1个小小传话员啦。

          这里给个思绪,详细完成起来也比拟复杂,当作是文原本处置便可。

          完好代码

          上面贴出我效劳器上的完好代码,有些私密的中央我做了些更改,届时依照本人的状况停止修正便可。

          <?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 ();
           /*
           * 微信客户端发送信息的时分会附带1些参数,详见官方文档。所以要依据差别的类型,来辨别做相干的处置。
           * 因而MsgType 就充任这样的1个辨别的标志
           */
           $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":
            // 发送1些音讯!
            $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;
           }
           }
          }
          /**
           * 界说为心中想难关的6个接口的数据发送花样模板
           */
          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'];
          }
          ?>

          总结

          最初往返顾1下,本次实验用到了哪些知识点。

          • PHP的面向工具办法编程复杂完成。
          • 接口处置的两种方式
          • 微信大众号后台私服的接入,处置,反应。
          • 前后真个交互,和谈天机械人的使用。

          其实,这些代码跟我1开端的想象照旧差异挺大的,本来是想完成1个“遥控器”,早晨想睡觉之前,用微信发1条下令“翻开电热毯”,半个小时后,电视看完了,去睡觉的时分发现被窝很温暖,是的,只需加上点硬件,这很容易完成啦再者冰箱了,电视了通通可以完成,那样估量救治的是“智能家居”了吧。