이번에는 PHP로 WeChat 원격 제어 서버를 개발하는 단계에 대해 자세히 설명하겠습니다. PHP로 WeChat 원격 제어 서버를 개발할 때의 주의사항은 무엇인가요?
WeChat 공익 개발이 매우 인기가 높으며, 미니 프로그램이 더욱 인기를 끌고 있습니다. 그래서 저도 그 재미에 동참해서 한번 시도해 봤습니다.
일반적인 기능은 아직 남아있지만 불완전하고 많은 곳을 다루지 않았습니다. 하지만 일반 텍스트로 통신하는 경우에는 문제가 없습니다.
WeChat 공개 계정의 원칙에 대해 간단히 이야기하겠습니다. 어쩌면 내 이해가 제대로 이루어지지 않았을 수도 있습니다. 잘못된 점이 있으면 비판과 조언을 환영합니다.
클라이언트가 WeChat 플랫폼에 요청을 보내고, WeChat 플랫폼은 해당 요청을 처리를 위해 프로그램에 넘겨준 후, 프라이빗 서버의 처리 결과를 얻어 클라이언트에 다시 피드백합니다. .
물론 “WeChat 공개 플랫폼”이 여기에 핵심적인 역할을 합니다. 재능 있는 사람과 낯선 사람이 각자의 개성을 보여줄 수 있는 무대, 플랫폼을 제공하는 것과 같다. 실제로 이는 위챗뿐만 아니라 알리바바에서도 마찬가지여서 주요 전자상거래 기업들이 자신들의 능력을 발휘할 수 있게 됐다.
구성 열기
첫 번째 단계는 WeChat 개발자 계정을 신청하는 것입니다. 개인의 경우 구독 계정을 선택하면 충분합니다. 온라인에는 관련 정보가 많고 매우 상세하므로 자세한 내용은 다루지 않겠습니다. 바로 요점을 살펴보겠습니다.
먼저 개발자 계정 로그인에 성공하신 후 아래와 같이 서버사이드 설정을 열 수 있습니다
활성화 완료 후, 본인의 서버 조건에 맞게 설정을 하시면 됩니다.
URL은 요청 데이터를 처리하기 위해 개인 서버에서 사용하는 주소입니다.
TOKEN은 토큰이므로 원하는 대로 설정하세요. 그러나 나중에 자신의 코드에서 이를 사용할 것이라는 점을 기억하십시오.
열쇠는 크게 사용하지 않으니 일단은 놔두셔도 됩니다.
필요에 따라 설정
설정 후 활성화하시면 됩니다. 이는 집에 있는 모든 전선을 장식하고 이제 이를 사용하고 스위치를 누르는 것과 같습니다. 아래와 같이
서버 구성 활성화
서버 환경
서버에 대해서는 공식 홈페이지에서 자세히 설명하고 있습니다.
https://mp.weixin.qq.com/wiki
공식 데모를 다운로드하여 시뮬레이션할 수도 있습니다.
공식 샘플
코드도 매우 간단합니다. 기본적으로 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; } } } ?>
핵심 아이디어는 서명을 확인하고, 요청을 처리하고, 결과를 피드백하는 것입니다.
여기서 말씀드리고 싶은 것은 Tencent가 실제로 해당 템플릿을 제거하고 블랙박스 모드를 직접 노출할 수 있다고 생각합니다. 이 경우 보안이 더 높아질 것입니다. 대부분의 경우 권한이 공개될수록 효과는 더 나빠질 수 있습니다.
Core Class
다음 단계는 나만의 처리 로직입니다. 공식 문서를 참고하세요. WeChat Public에는 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进行处理即可。
拓展
拓展部分,是我自己异想天开往上加的。
添加机器人
调用一个机器人接口,来代替自己发送回复,技能让用户得到一个良好的用户体验,还能愉悦大众,何乐而不为?
我这边测试了两个接口,一个是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를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명模式
手机相对于电脑一个很大的优点就是便携,我们虽然不能随时随地携带电脑,但是却能使用手机来代替。很多时候对服务器的管理需要的PHP를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명很简单,但是远程登录的时候也不方便。这个时候就用微信来帮忙传话也是不错的啦。
我平时喜欢使用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를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명' || $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를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명模式'){ $msgType = 'text'; $contentStr = "进入PHP를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명模式,开始对服务器进行管理!\n接下来将依据您输入的PHP를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명对服务器进行管理!"; 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를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명“打开电热毯”,半个小时后,电视看完了,去睡觉的时候发现被窝很暖和,是的,只要加上点硬件,这很容易实现啦再者冰箱了,电视了统统可以完成,那样估计就诊的是“智能家居”了吧。
相信看了本文案例你已经掌握了方法,更多精彩请关注php中文网其它相关文章!
推荐阅读:
위 내용은 PHP를 사용하여 WeChat 원격 제어 서버를 개발하는 단계에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!