承接上文的WeChatCallBack

在WeChatCallBack类的成员变量中定义了各种消息都会有的字段,这些字段在init函数中赋值。同时也把解析到的XML对象作为这个类的成员变量$_postObject并在init中赋值,目的是在实现具体公众账号的业务逻辑时,具体的各类消息的特殊字段可以通过它来获取。

process函数时实现具体公众账号的业务逻辑时需要重载的函数,默认的实现是返回一个“未实现”的错误提示。

  本文的重点是接入脚本,接入脚本是项目根目录的interface.php,其代码清单如下文所示:

  <?php

  require_once dirname(__FILE__) . '/common/GlobalFunctions.php';

  function checkSingnature()

  {

    $signature = $_GET["signature"];

    $timestamp = $_GET["timestamp"];

    $nonce = $_GET["nonce"];

    $token = WEIXIN_TOKEN;

    $tmpArr = array($token, $timestamp, $nonce);

    sort($tmpArr);

    $tmpStr = implode( $tmpArr );

    $tmpStr = shal( $tmpStr );

    if( $tmpStr == $signature ) {

      return true;

    } else {

      return false;

    }

  }

  if(checkSignature()) {

    if($_GET["echostr"]) {

      echo $_GET["echostr"];

      exit(0);

    }

  } else {

    // 恶意请求: 获取来源IP, 并写入日志

    $ip = getIp();

    interface_log(ERROR, EC_OTHER, 'malicious: ' . $ip);

    exit(0);

  }

  function getWeChatObj($toUserName) {

    if($toUserName == USERNAME_FINDFACE) {

      require_once dirname(__FILE__) . '/class/

      WeChatCallBackMeiri10futu.php' ;

      return new WeChatCallBackMeir10futu();

    }

    if($toUserName == USERNAME_MR)  {

      require_once dirname(__FILE__) . '/class/

      WeChatCallBackMeir10futu.php' ;

      return new WeChatCallBackMeir10futu();

    }

    if($toUserName == USERNAME_ES) {

      require_once dirname(__FILE__) . '/class/

      WeChatCallBackEchoServer.php' ;

      return new WeChatCallBackEchoServer();

    }

    require_once dirname(__FILE__) . '/class/WeChatCallBcak.php' ;

    return new WeChatCallBack();

  }

  function exitErrorInput() {

    echo 'error input!' ;

    interface_log(INFO, EC_OK, "***** interface request end ******") ;

    interface_log(INFO, EC_OK, "********************** ******") ;

    interface_log(INFO, EC_OK, "") ;

    exit( 0 );

  }

  $postStr = file_get_contents ( "php://input" );

  

  interface_log(INFO, EC_OK, "");

  interface_log(INFO, EC_OK, "*****************************");

  interface_log(INFO, EC_OK, "***** interface request start *****");

  interface_log(INFO, EC_OK, 'request: '  .  var_export($_GET, ture)) ;

  if (empty ( $postStr )) {

    interface_log ( ERROR, EC_OK, "error input!" );

    exitErrorInput();

  }

  // 获取参数

  $postObj = simplexml_load_string  ( $postStr,  'SimpleXMLElement',

  LIBXML_NOCDATA ) ;

  $toUserName = ( string ) trim ( $postObj->ToUserName ) ;

  if (! $toUserName) {

    interface_log ( ERROR, EC_OK, "error input!" ) ;

    exitErrorInput() ;

  } else {

    $wechatObj = getWeChatObj ( $ toUserName ) ;

  }

  retStr = $ wechatObj->process ();

  interface_log(INFO, EC_OK, "***** interface request end *****") ;

  interface_log(INFO, EC_OK, "****************************") ;

  interface_log(INFO, EC_OK, "");

  ?>

  Interface.php逻辑描述:

  1.使用checkSignature函数验证请求是否合法,在不合法的情况下,记录恶意的来源IP。

  2.获取POST数据,解析XML数据,根据ToUserName来决定是发往哪一个公众账号的消息,然后加载对应的文件,获得对应的对象(getWeChatObj函数)。

  3.调用对象的init函数初始化对象。

  4.调用对象的process函数处理公众账号逻辑,得到返回消息字符串。

  5.返回消息。

  获取来源IP函数:

  function getIp ()

  {

    if (isset($_SERVER)) {

        if (isset($_SERVER["HTTP_X_FORWARDED_FOR"])) {

            $realip = $_SERVER["HTTP_X_FORWARDED_FOR"] ;

        } else if (isser($_SERVER["HTTP_CLIENT_IP"]))  {

            $realip = $_SERVER["HTTP_CLIENT_IP"] ;

        } else {

            $realip = $SERVER["REMOTE_ADDR"];

        }

    } else {

        if (getenv(""HTTP_X_FORWARDED_FOR")) {

            $realip = getenv("HTTP_X_FORWARDED_FOR") ;

        } else if (getenv("HTTP_CLIENT_IP")) {

            $realip = getenv("HTTP_CLIENT_IP") ;

        } else {

            $realip = getenv("REMOVE_ADDR") ;

        }

    }

    return $realip;

  }

___________over____________

接入脚本interface.php实现代码的更多相关文章

  1. Tsung脚本中使用动态参数(一)---直接在脚本里编写Erlang代码

    杀死一个程序猿,只要改三次需求.同理,杀死一个接口自动化测试人员,只要改三次接口数据处理方式.我目前的状态,改了一次接口数据处理方式,有一种胸闷的感觉. 因为改需求,所以,要改脚本.T_T.所以,才有 ...

  2. Unity3D脚本调用Objective C代码实现游戏内购买

    0.开篇吐槽: 一年之内从WP转到iOS,又从iOS转到U3D,真心伤不起. 1.Unity3D脚本调用OC代码的原理: 其实也没啥神秘的,因为OC是和C互通的 ,C#又可以通过DllImport的形 ...

  3. grep 查找bash脚本中的注释代码

    出于安全性的考虑,不建议在bash脚本中注释掉不使用的代码.也就是说如果某段代码不使用了,那么应该删除掉,而不是简单地注释掉.假如你突然意识到这一点,而以前并没有遵从这个原则,现在需要找出脚本中的注释 ...

  4. 小技巧找出一个php的cron脚本出问题的代码行

    这个小技巧虽然很小,但是很有用. 我写了一个cron脚本,但是隔一天发现,这个昨天的cron脚本还一直在跑着,没有停下来,一定是里面有个程序堵住了. 但是如果我重新跑又需要很多时间.这个怎么办? 现在 ...

  5. 如何在batch脚本中嵌入python代码

    老板叫我帮他测一个命令在windows下消耗的时间,因为没有装windows那个啥工具包,没有timeit那个命令,于是想自己写一个,原理很简单: REM timeit.bat echo %TIME% ...

  6. Java Native Interface调用C++代码

    概述 Java Native Interface译为Java原生接口,简称JNI.Java并不是完美的,它的不足体现在运行速度要比传统的C++慢上许多,并且无法直接访问到操作系统底层,为此Java提供 ...

  7. phpMyAdmin setup.php脚本的任意PHP代码注入漏洞

    phpMyAdmin (/scripts/setup.php) PHP 注入代码 此漏洞代码在以下环境测试通过:      phpMyAdmin 2.11.4, 2.11.9.3, 2.11.9.4, ...

  8. [19/04/19-星期五] Java的动态性_脚本(Script,脚本)引擎执行JavaScript代码

    一.概念 Java脚本引擎是jdk 6.0之后的新功能. 使得Java应用程序可以通过一套固定的接口与各种脚本引擎交互,从而达到在Java平台上调用各种脚本语言的目的. Java脚本API是连接Jav ...

  9. [自动化-脚本]002.cocos2dx-lua lua代码windows加密批处理

    在开发软件的时候,我们都会在项目上线时候对代码进行加密,用来防止被不法分子盗走牟利.不同的语言有不同的加密方式,比较出名的有加壳,代码混淆等.在Lua开发cocos2dx的时候,框架会有提供加密的脚本 ...

随机推荐

  1. linux入门教程(一) 关于linux的历史

    很多关于linux的书籍在前面章节中写了一大堆东西来介绍linux,可惜读者看了好久也没有正式开始进入linux的世界,这样反而导致了他们对linux失去了一些兴趣,而把厚厚的一本书丢掉. Linux ...

  2. SSL/TLS/WTLS原理(密钥协商的形象化比喻:验证服务器的身份,用服务器的公钥协商加密格式,然后再加密具体的消息,TCP传递SSL处理后的数据)good

    一 前言 首先要澄清一下名字的混淆: 1 SSL(Secure Socket Layer)是netscape公司设计的主要用于web的安全传输协议.这种协议在WEB上获得了广泛的应用. 2 IETF( ...

  3. Android:简单联网获取网页代码

    设置权限,在AndroidManifest.xml加入 <uses-permission android:name="android.permission.INTERNET" ...

  4. [转]更新Debian软件源

    转自:香神无涯 sudo cp /etc/apt/sources.list /etc/apt/sources.list_bak #备份一下软件源sudo vi /etc/apt/sources.lis ...

  5. PCA understanding

    PCA understanding 我们希望获取玩具的位置,事实上我们只需要知道玩具在x轴的位置就可以了(但现实不知道).我们利用三个坐标轴,获取了2*3维度的数据,现实中我们如何通过分析六维度数据来 ...

  6. tcpdump抓SQL

    前言:假设如果有个服务器几十个链接突然达到上千个链接,show processlist,general_log,还有慢查询日志这些都不能用,你怎么把这些链接过来的SQL情况了解清楚,如果你觉得那些好用 ...

  7. linux关机和重启的命令[转]

    如果你很急着关机或者重启话,那么关机就是init 0,重启就是init 6或者reboot Linux中常用的关机和重新启动命令有shutdown.halt.reboot以及init,它们都可以达到关 ...

  8. BZOJ2253: [2010 Beijing wc]纸箱堆叠

    题解: 其实就是求三维偏序最长链.类似于三维逆序对,我们可以用树状数组套平衡树来实现. DP方程 :f[i]=max(f[j]+1) a[j]<a[i] 我们按一维排序,另一位建立树状数组,把第 ...

  9. Asp.net 后台添加Meta标签方法

    Asp.net 后台添加Meta标签方法包括keywords,CSS.JS 下面是从Asp.net 后台添加CSS.JS.Meta标签的写法,我们这里写成函数方便以后使用.如果函数放在页面类中, Pa ...

  10. BZOJ 3573 米特运输

    语文题... 原来除了hash还可以取对数啊orz #include<iostream> #include<cstdio> #include<cstring> #i ...