微信公众好的开发很火,小程序更火。于是也凑个热闹,尝试了一把。
大致的功能还是有的,不过是不全,很多地方我没有进行处理。不过对于纯文本方式的交流,已经没有问题啦。
下面大致的讲讲微信公众号的原理吧。可能我理解的有些不到位,如果有些许不当,欢迎批评指教。
客户端发送给微信平台请求,微信平台将请求转发给私服,交给程序处理之后,获取到私服的处理结果,然后反馈给客户端。
当然,这其中起到核心作用的自然是“微信公众平台”啦。相当于提供了一个舞台,一个能让各位能人异士展现出各自的特色的平台。其实,不仅微信如此,阿里同样是这样,如此各大电商才能一展手脚不是。
开启配置
这第一步,就是先申请一个微信开发者账号,个人的话选择订阅号就足够了。网上相关的资料很多,也很详细,我就不多说了。咱们直奔主题好了。
首先登陆开发者账号成功后,开启服务器端的设置即可,如下图
开启完成,根据自己服务器的情况进行一下设置即可。
URL就是你的私服用于处理请求数据的地址
TOKEN就是一个令牌,随便设置。不过记住待会自己的代码上会用到。
至于密钥嘛,没什么较大的作用,暂且可以先不用管。
按需设置
设置完,就可以启用了。这就好比家里的电线全部装修好了,现在要使用,按下开关一样。如下图
启用服务器配置
服务器环境
关于服务器这块,网址上讲解的也是很详细的啦。
http://mp.weixin.qq.com/wiki
我们还可以下载官方的demo来模拟。
官方样本
代码也很简单。基本上学过了PHP基本语法的都能够看得懂。
?php * wechat php test//define your tokendefine( TOKEN , weixin $wechatObj = new wechatCallbackapiTest();$wechatObj- valid();html' target='_blank'>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;?
核心思路,无非检验一下签名,处理一下请求,反馈一下结果罢了。
这里我不得不想说的就是,我觉得腾讯其实可以将那些个模板什么的去掉,直接暴露出黑盒模式,这样的话安全性会更高一点。很多时候,权限放的越开,效果可能越差。
核心类
接下来就是我自己的处理逻辑了,参照官方文档。微信公众好上有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 mixedfunction 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 tokendefine ( 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的面向对象方法编程简单实现。
接口处理的两种方式
微信公众号后台私服的接入,处理,反馈。
前后端的交互,以及聊天机器人的应用。
其实,这些代码跟我一开始的设想还是差别挺大的,原本是想实现一个“遥控器”,晚上想睡觉之前,用微信发一条命令“打开电热毯”,半个小时后,电视看完了,去睡觉的时候发现被窝很暖和,是的,只要加上点硬件,这很容易实现啦再者冰箱了,电视了统统可以完成,那样估计就诊的是“智能家居”了吧。
您可能感兴趣的文章:CI框架(CodeIgniter)操作redis的方法的详解
php使用imagecopymerge()函数创建半透明水印的详解
一个中高级PHP工程师所应该具备的能力
以上就是PHP开发之用微信远程遥控服务器的相关讲解的详细内容,PHP教程
郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。
新闻热点
疑难解答