开发微信公众平台接口参数调试-判断用户行为

 更新时间:2016年11月25日 17:24  点击:1490
微信开发的时候,发现有个重要的变量$postObj,获得了一个xml结构装入的对象里因为用户发来的事件,之前只知道用户发送一个消息,我进行处理。

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

 代码如下 复制代码

 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.111cn.net353512</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+’ 读写方式打开,将文件指针指向文件末尾。如果文件不存在则尝试创建之。
*/

 代码如下 复制代码
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);
}
最近在捣鼓微信公共平台提供的API,等确实一个获取用户信息的API。所以没有办法,只能自己去获取,手动填写当然可以解决问题,当然编程不就是为了让生活变的更简单么?

当然,远程抓取微信公共平台数据的想法就油然而生,当然第一个想到了CURL。

CURL可以远程提交表达,我感觉微信是提议让我们怎么的,只要不是恶意刷接口,就不会出现验证码。

主要注意的几个问题

1.远程登录接口是时候的HTTPS协议。
2.登录成功后页面有跳转。
3.返回的HTML页面是可以直接输出的。
下面展示了一个CURL的具体写法

 代码如下 复制代码
//微信远程登录绑定账号
   public function Curl_login($username,$pwd){
    $config_token = "XiaoDengPHP";
    $pwd = md5($pwd);
    $url = "https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN";
    $postArray = array("username=".$username,"pwd=".$pwd,"imgcode=","f=json");
    $fields = implode("&", $postArray);
    $filedir = $_SERVER['DOCUMENT_ROOT']."/Cookies";
    $cookie_file =  $filedir."/cookie.txt";
    $ch = curl_init();  www.111cn.net
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 1); //表示是https协议提交
    curl_setopt($ch, CURLOPT_HEADER, 0); //不返回header部分
    curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
    curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file); //生产Cookies并保存在指定目录下
    curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); //将curl_exec()获取的信息以文件流的形式返回,而不是直接输出。
    curl_setopt($ch, CURLOPT_REFERER,"https://mp.weixin.qq.com/cgi-bin/login?lang=zh_CN"); //跳转指向
    $result = curl_exec($ch);
    return json_decode($result);
    // 关闭CURL会话
    curl_close($ch);
}

上面这个方法就实现了,远程登录微信公共平台,接下来的事,就是去让账号变成开发者模式,一样的CURL。
注意这次的curl要带上cookies而不是生产cookies
重点代码在于验证服务器的相应,你需要设置一个服务器的连接和一个token

 代码如下 复制代码
public function auth($token)
  {
       $data = array(
       $_GET['timestamp'],
       $_GET['nonce'],
       $token);
       $sign = $_GET['signature'];
       sort($data);
       $signature = sha1(implode($data));
        if($signature === $sign){
              echo ($_GET['echostr']);
          exit;
        }else{
          return false;
          }
 }

这样如果开通成功了,应该会返回一个MES=302的json数据和一个微信平台认证的token的信息。

只要你细心,你就会发现,微信连接里面TOKEN是一个动态变化的,但有是在一段时间内不变的。

所以你需要这个token来构造URL,来获取其他页面信息。

但开发现过程中,你一定遇到一个很崩溃的问题。

现在多数网站都有防盗链一些简单设置了最常用的就是apache,nginx,iis设置了,那么这种设置是不是不可破的呢,答案是否写了,下面我们一起来看破解方法。

有自己的主机一般都会设计"防盗链", 其实包括图片防盗链,和下载防盗链等,如:

使用.htaccess设置防盗链

 代码如下 复制代码

RewriteEngine on
RewriteCond %{HTTP_REFERER} !^$
RewriteCond %{HTTP_REFERER} !^http://(www.)?xuexb.com/.*$ [NC]
RewriteRule .(gif|jpg)$ http://www.111cn.net /image.gif [R,L]


nginx设置防盗链

 代码如下 复制代码

location ~* .(gif|jpg|png|swf|flv)$ {
 valid_referers none blocked 111cn.net;
 if ($invalid_referer) {
  rewrite ^/ http://111cn.net /234_s.gif;
  #return 404;
 }
}

但怎么破解防盗链呢? 一般的防盗链是判断来路是否为自己的域名, 我们可以使用 php 内置的 file_get_contents 方法来请求这个图片(当然别的后端语言也有类似的方法), 如:
//getImg.php?url=目标图片连接

 代码如下 复制代码
<?php
header('Content-type: image/jpeg');
echo file_get_contents(isset($_GET["url"])?$_GET["url"]:'http://xxxx域名 /images/v1/loading-16-16.gif');
?>

php代码片段看例子:

1, 直接加载防盗链图片: 

破解防盗链图片
 
2, 通过php读取图片:

破解防盗链图片

在Drupal 7 以后我们可以轻松使用类似模态框的overlay模块来实现一个弹出层。下面我介绍2个实例,如何自定义扩展Overlay。

Drupal overlay examples
扩展 Overlay 模块头部显示用户头像实例
在你的自定义模块中加入overlay脚本JS文件,通过overlay的钩子:

 代码如下 复制代码

function mymodule_overlay_child_initialize() {
  // Add our custom JavaScript.
  drupal_add_js(drupal_get_path('module', 'mymodule') . '/overlay-child.js');
}然后通过Add JS 头像路径到header中。

/**
 * @see hook_js_alter().
 */
function yourtheme_js_alter(&$javascript) {
  global $theme, $user;
  if (isset($user->picture) && is_string($user->picture)) {
    $picture = file_load($user->picture);
  } www.111cn.net
  elseif (isset($user->picture) && is_object($user->picture)) {
    $picture = $user->picture;
  }
  if (isset($picture) && $picture && isset($picture->uri)) {
    $filepath = file_create_url($picture->uri);
    $javascript['settings']['data'][]['user_picture'] = $filepath;
  }
}

在overlay-child.js文件中加入以下Javascript 代码:

 代码如下 复制代码

(function ($) {
    Drupal.behaviors.yourmodule = {
        attach: function (context) {
            $('#overlay:not(.your-module-adjusted)', context).each(function() {
                if (Drupal.settings.user_picture) {
                    $('#overlay-titlebar', this).css('padding-left', 0);
                    $('#overlay-title-wrapper', this).find('h1#overlay-title').prepend('<img src="'+Drupal.settings.user_picture+'" />');
                }
            }).addClass('your-module-adjusted');
            $('.overlay .footer').hide();
        }
    };
})(jQuery);

完成后,你就可以看到如上面的图片的效果。

修改overlay覆盖层的宽度和隐藏元素实例
下面这个例子向你展示如何修改overlay (覆盖层) 内的内容,当一个指定的节点类型(test)被展示在overlay 覆盖层。这个脚本向你展示修改overlay层的宽度为450px 和 隐藏一些不想见到的元素。


在你的模块中同样需要想上面的例子那样加入overlay-child.js脚本。

在overlay-child.js文件中加入以下Javascript 代码:

 代码如下 复制代码

(function ($) {
  // Adjust the overlay dimensions.
  Drupal.behaviors.myModule = {
    attach: function (context) {
      $('#overlay:not(.mymodule-adjusted)', context).each(function() {
        var $test = $(this).find('.node-type-test');
        if ($test.length){
          // adjust the overlay
          $(this).css({
            'width'     : '450px',
            'min-width' : '450px'
          });www.111cn.net
          $('.add-or-remove-shortcuts', this).hide();  // hide "add short-cut" button
          $('#branding', this).hide();  // hide branding container
        }
      }).addClass('mymodule-adjusted');
    }
  };
})(jQuery);


如果你想修改所有overlay层里的布局,请找到overlay.tpl.php然后修改它。

 

利用php中的preg_replace正则匹配函数过滤掉网页中的js代码,preg_replace()中的第四个参数中表示替换的次数,默认是-1,表示替换全部;如果只想替换2次,可以写为 preg_replace($p1,$p2,$p3,2)。

匹配的规则不能用 "//<script.*<//script>//i",因为它不能匹配到换行符,那么多行js就匹配不掉了。要用 "//<script[sS]*?<//script>//i"。里面的?表示尽可能少重复,也就是匹配最近的一个<//script>。

源码范例:

php匹配js

 代码如下 复制代码

<?php

 

 header("Content-type:text//html;charset=utf-8");

 $str = '<script type="text//javascript" src="dd.js"><//script>

测试php正则匹配掉js代码<script type="text//javascript" src="123.js"><//script>

<script type="text//javascript">

 var aa = "sdsds";

 alert(aa);

<//script>

测试php正则匹配掉js代码';

 www.111Cn.net


 $preg = "//<script[sS]*?<//script>//i";

 $newstr = preg_replace($preg,"",$str,3);    ////第四个参数中的3表示替换3次,默认是-1,替换全部

 echo $newstr;

 


?>

[!--infotagslink--]

相关文章

  • c# 三种方法调用WebService接口

    这篇文章主要介绍了c# 三种方法调用WebService接口的相关资料,文中示例代码非常详细,帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-07
  • vue接口请求加密实例

    这篇文章主要介绍了vue接口请求加密实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-12
  • SpringBoot接口接收json参数解析

    这篇文章主要介绍了SpringBoot接口接收json参数解析,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-10-19
  • C#简单了解接口(Interface)使用方法

    这篇文章主要介绍了C#简单了解接口(Interface)使用方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-12-08
  • Feign接口方法返回值设置方式

    这篇文章主要介绍了Feign接口方法返回值设置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-07-08
  • C# Rx的主要接口深入理解

    这篇文章主要介绍了C# Rx的主要接口深入理解的相关资料,需要的朋友可以参考下...2020-06-25
  • vue设置全局访问接口API地址操作

    这篇文章主要介绍了vue设置全局访问接口API地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-14
  • 如何设计一个安全的API接口详解

    在日常开发中,总会接触到各种接口,前后端数据传输接口,第三方业务平台接口,下面这篇文章主要给大家介绍了关于如何设计一个安全的API接口的相关资料,需要的朋友可以参考下...2021-08-12
  • php怎么写api接口?php写api接口的实例代码

    php怎么写api接口?本文介绍了php写api接口的实例代码,有兴趣的同学可以参考一下。 http://localhost/openUser.php?act=get_user_list&type=json在这里openUser.php...2017-07-06
  • vue配置多代理服务接口地址操作

    这篇文章主要介绍了vue配置多代理服务接口地址操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-09-08
  • C#处理和对接HTTP接口请求的方法

    下面通过四步给大家介绍了c#处理和对接http接口请求的方法,分步骤介绍的非常详细,具有参考借鉴价值,感兴趣的朋友一起看下吧...2020-06-25
  • Java接口DAO模式代码原理及应用详解

    这篇文章主要介绍了Java接口DAO模式代码原理及应用详解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-11-03
  • C#实现两接口中同名方法实例分析

    这篇文章主要介绍了C#实现两接口中同名方法,涉及C#接口与方法的相关操作技巧,需要的朋友可以参考下...2020-06-25
  • c# 接口使用实例

    这篇文章主要介绍了c#接口使用的实例,文中讲解非常细致,代码帮助大家更好的理解和学习,感兴趣的朋友可以了解下...2020-07-17
  • SpringData Repository接口用法解析

    这篇文章主要介绍了SpringData Repository接口用法解析,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-08-27
  • 微信小程序通过api接口将json数据展现到小程序示例

    这篇文章主要介绍了微信小程序通过api接口将json数据展现到小程序示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2017-01-23
  • 详解c# 接口IDisposable的用法

    这篇文章主要介绍了详解c# 接口IDisposable的用法,帮助大家更好的理解和学习c#,感兴趣的朋友可以了解下...2020-12-08
  • 深入浅析Restful接口的两种使用方式

    restful接口常用的两种方式是get和post.接下来通过本文给大家介绍Restful接口的两种使用方式,本文给大家介绍的非常详细,需要的朋友参考下吧...2020-06-25
  • Python优化列表接口进行分页示例实现

    最近,在做测试开发平台的时候,需要对测试用例的列表进行后端分页,在实际去写代码和测试的过程中,发现这里面还是有些细节的,故想复盘一下...2021-09-29
  • vue 接口请求地址前缀本地开发和线上开发设置方式

    这篇文章主要介绍了vue 接口请求地址前缀本地开发和线上开发设置方式,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-08-13