php版微信公众平台接口参数调试实现判断用户行为的方法,PHP开发之用微信远程遥控服务器

 摘要

微信公众好的开发很火,小程序更火。于是也凑个热闹,尝试了一把。

大致的功能还是有的,不过是不全,很多地方我没有进行处理。不过对于纯文本方式的交流,已经没有问题啦。

图片 1

图片 2

PHP开发之用微信远程遥控服务器,php开发遥控服务器

本文实例讲述了php版微信公众平台接口参数调试实现判断用户行为的方法。分享给大家供大家参考,具体如下:

环境搭建

下面大致的讲讲微信公众号的原理吧。可能我理解的有些不到位,如果有些许不当,欢迎批评指教。

客户端发送给微信平台请求,微信平台将请求转发给私服,交给程序处理之后,获取到私服的处理结果,然后反馈给客户端。

当然,这其中起到核心作用的自然是“微信公众平台”啦。相当于提供了一个舞台,一个能让各位能人异士展现出各自的特色的平台。其实,不仅微信如此,阿里同样是这样,如此各大电商才能一展手脚不是。

开启配置

这第一步,就是先申请一个微信开发者账号,个人的话选择订阅号就足够了。网上相关的资料很多,也很详细,我就不多说了。咱们直奔主题好了。

首先登陆开发者账号成功后,开启服务器端的设置即可,如下图

图片 3

开启完成,根据自己服务器的情况进行一下设置即可。

  • URL就是你的私服用于处理请求数据的地址
  • TOKEN就是一个令牌,随便设置。不过记住待会自己的代码上会用到。
  • 至于密钥嘛,没什么较大的作用,暂且可以先不用管。

图片 4

按需设置

设置完,就可以启用了。这就好比家里的电线全部装修好了,现在要使用,按下开关一样。如下图

图片 5

启用服务器配置

服务器环境

关于服务器这块,官网上讲解的也是很详细的啦。

我们还可以下载官方的demo来模拟。

图片 6

官方样本

代码也很简单。基本上学过了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;
 }
 }
}
?>

核心思路,无非检验一下签名,处理一下请求,反馈一下结果罢了。

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

核心类

接下来就是我自己的处理逻辑了,参照官方文档。微信公众好上有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的面向对象方法编程简单实现。
  • 接口处理的两种方式
  • 微信公众号后台私服的接入,处理,反馈。
  • 前后端的交互,以及聊天机器人的应用。

其实,这些代码跟我一开始的设想还是差别挺大的,原本是想实现一个“遥控器”,晚上想睡觉之前,用微信发一条命令“打开电热毯”,半个小时后,电视看完了,去睡觉的时候发现被窝很暖和,是的,只要加上点硬件,这很容易实现啦再者冰箱了,电视了统统可以完成,那样估计就诊的是“智能家居”了吧。

 摘要

微信公众好的开发很火,小程序更火。于是也凑个热闹,尝试了一把。

大致的功能还是有的,不过是不全,很多地方我没有进行处理。不过对于纯文本方式的交流,已经没有问题啦。

图片 7

图片 8

微信开发的时候,发现有个重要的变量$postObj,获得了一个xml结构装入的对象里因为用户发来的事件,之前只知道用户发送一个消息,我进行处理.

您可能感兴趣的文章:

  • 微信小程序上传图片到服务器实例代码
  • 本地搭建微信小程序服务器的实现方法
  • 微信小程序图片选择、上传到服务器、预览(PHP)实现实例
  • 微信小程序访问node.js接口服务器搭建教程
  • 微信小程序
    消息推送php服务器验证实例详解
  • 微信公众平台开发-微信服务器IP接口实例(含源码)
  • 微信小程序
    解决请求服务器手机预览请求不到数据的方法
  • 微信小程序 Windows2008
    R2服务器配置TLS1.2方法
  • java微信开发API第一步
    服务器接入
  • C#微信开发(服务器配置)

环境搭建

下面大致的讲讲微信公众号的原理吧。可能我理解的有些不到位,如果有些许不当,欢迎批评指教。

客户端发送给微信平台请求,微信平台将请求转发给私服,交给程序处理之后,获取到私服的处理结果,然后反馈给客户端。

当然,这其中起到核心作用的自然是“微信公众平台”啦。相当于提供了一个舞台,一个能让各位能人异士展现出各自的特色的平台。其实,不仅微信如此,阿里同样是这样,如此各大电商才能一展手脚不是。

开启配置

这第一步,就是先申请一个微信开发者账号,个人的话选择订阅号就足够了。网上相关的资料很多,也很详细,我就不多说了。咱们直奔主题好了。

首先登陆开发者账号成功后,开启服务器端的设置即可,如下图

图片 9

开启完成,根据自己服务器的情况进行一下设置即可。

  • URL就是你的私服用于处理请求数据的地址
  • TOKEN就是一个令牌,随便设置。不过记住待会自己的代码上会用到。
  • 至于密钥嘛,没什么较大的作用,暂且可以先不用管。

图片 10

按需设置

设置完,就可以启用了。这就好比家里的电线全部装修好了,现在要使用,按下开关一样。如下图

图片 11

启用服务器配置

服务器环境

关于服务器这块,官网上讲解的也是很详细的啦。

我们还可以下载官方的demo来模拟。

图片 12

官方样本

代码也很简单。基本上学过了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;
 }
 }
}
?>

核心思路,无非检验一下签名,处理一下请求,反馈一下结果罢了。

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

核心类

接下来就是我自己的处理逻辑了,参照官方文档。微信公众好上有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的面向对象方法编程简单实现。
  • 接口处理的两种方式
  • 微信公众号后台私服的接入,处理,反馈。
  • 前后端的交互,以及聊天机器人的应用。

其实,这些代码跟我一开始的设想还是差别挺大的,原本是想实现一个“遥控器”,晚上想睡觉之前,用微信发一条命令“打开电热毯”,半个小时后,电视看完了,去睡觉的时候发现被窝很暖和,是的,只要加上点硬件,这很容易实现啦再者冰箱了,电视了统统可以完成,那样估计就诊的是“智能家居”了吧。

摘要 微信公众好的开发很火,小程序更火。于是也凑个热闹,尝试了一把。
大致的功…

今天要弄个用户订阅就给推送一个消息的功能,却发现不知道如何判断用户是订阅的操作,还是取消订阅,还是发消息,代码如下:

public function responseMsg()
{
 global $db;
 //get post data, May be due to the different environments
 $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
 $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
 writeover("msg.txt",$postStr."rn","a+");
 //。。。。。
}

发现$postStr是之前没有封装的字符串,直接打印,即可知道用户的行为了,测试输出的文件如下:

<xml><ToUserName><![CDATA[gh_a64528aca3b]]></ToUserName>
<FromUserName><![CDATA[oSgH_jveTxJSlFK_6QSiGeVaSyk]]></FromUserName>
<CreateTime>1394705044</CreateTime>
<MsgType><![CDATA[text]]></MsgType>
<Content><![CDATA[ha]]></Content>
<MsgId>5990212551746www.phpfensi.com353512</MsgId>
</xml>

MsgType即可判断用户行为text表示用户输入了一条文本信息,如果是订阅,那么就是event
大家自己测试吧.

一个新用户关注公众账号发送的消息的例子,代码如下:

<xml><ToUserName><![CDATA[gh_a5218aca3b]]></ToUserName>
<FromUserName><![CDATA[oSgH_jveTxJSlFK_6QSiGeVyk]]></FromUserName>
<CreateTime>1394706271</CreateTime>
<MsgType><![CDATA[event]]></MsgType>
<Event><![CDATA[subscribe]]></Event>
<EventKey><![CDATA[]]></EventKey>
</xml>

这样就可以得到具体的事件类型了.

$msgtype =
$postObj->MsgType;能判断用户的行为,后续的操作就方便多了.

附上写入日志文件的代码:

‘r’ 只读方式打开,将文件指针指向文件头。

‘r+’ 读写方式打开,将文件指针指向文件头。

‘w’
写入方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。

‘w+’
读写方式打开,将文件指针指向文件头并将文件大小截为零。如果文件不存在则尝试创建之。

‘a’ 写入方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。

‘a+’ 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。

PHP实例代码如下:

function writeover2($filename,$data,$method="rb+",$iflock=1)
{
 @touch($filename);/*文件不存在则创建之.可以采用file_exists验证并其他创建文件函数代替.测试结果效率相当*/
 $handle=@fopen($filename,$method);
 if($iflock){
  flock($handle,LOCK_EX);
 }
 fwrite($handle,$data);
 if($method=="rb+") ftruncate($handle,strlen($data));
 fclose($handle);
}

更多关于PHP相关内容感兴趣的读者可查看本站专题:《PHP微信开发技巧汇总》、《PHP编码与转码操作技巧汇总》、《PHP网络编程技巧总结》、《PHP基本语法入门教程》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总》

希望本文所述对大家PHP程序设计有所帮助。

您可能感兴趣的文章:

  • php实现微信企业号支付个人的方法详解
  • php微信浏览器分享设置以及回调详解
  • php版微信公众平台开发之验证步骤实例详解
  • PHP对接微信公众平台消息接口开发流程教程
  • 微信公众平台开发接口PHP
    SDK完整版
  • PHP使用Face++接口开发微信公众平台人脸识别系统的方法
  • php微信公众平台配置接口开发程序
  • php微信公众平台交互与接口详解
  • php版微信公众平台接口开发之智能回复开发教程
  • PHP编程之微信公众平台企业号验证接口示例【回调操作】