承接上文的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. [PHP]如何在百度(BAE)和新浪(SAE)的云平台使用PHP连接MySQL并返回结果数据

    <?php $dbname = 'VnOTxPFWoxzUBLtrQCCg'; $host = getenv('HTTP_BAE_ENV_ADDR_SQL_IP'); $port = geten ...

  2. lintcode 中等题:Simplify Path 简化路径

    题目 简化路径 给定一个文档(Unix-style)的完全路径,请进行路径简化. 样例 "/home/", => "/home" "/a/./b ...

  3. python pdb调试模块使用

    一般在需要调试的文件加入下面代码即可 ################ _DEBUG = True ... if _DEBUG == True import pdb pdb.set_trace() # ...

  4. Retrofit所有知识场景汇总

    https://futurestud.io/blog/retrofit-getting-started-and-android-client Retrofit Series Overview Gett ...

  5. Learning Lua Programming (2) Lua编程基础

    开始学习Lua编程,首先从一些简单的语法开始. 一.编辑环境 下面推荐一个Lua编程的IDE,感觉是很强大的.ZeroBrane Studio,windows平台,mac平台都有.点击打开链接  官方 ...

  6. TCP protocol

    he characteristics of TCP protocol TCP (which means Transmission Control Protocol) is one of the mai ...

  7. MTK6577+Android4.04编译

    MTK6577+Android4.04编译 编译命令 ./mk new 出错信息如下: **********checkingEnv************ Your building environm ...

  8. static,this,抽象类,接口和包

    1. static 1)静态变量:Java虚拟机为静态变量开辟单独的存储空间,所以所有的对象内部的静态变量在内存中都指向同一个地址,那么不管哪个对象改变这个成员变量,所有对象中该成员变量的值都发生变化 ...

  9. ggplot2 demo

    title <- rep("A Really Rather Long Text Label", 25)value <- runif(25, 1,10)spacing & ...

  10. ASP.NET中如何删除最近打开的项目和文件的记录

    ASP.NTET中总是保留最近打开的项目和文件的记录,甚至是已删除的它也不删.下面介绍几种删除的方法: 第一种:建立一个bat文件,以后双击即可清除,内置代码如下: @echo off@REG Del ...