admin管理员组

文章数量:1614997

官网下载网址http://mp.weixin.qq/mpres/htmledition/res/wx_sample.20140819.zip

<?php
/**
  * wechat php test
  */

//define your token
define("TOKEN", "weixin");//定义常量,储存TOKEN
$wechatObj = new wechatCallbackapiTest();//实例化对象
$wechatObj->valid();//调用验证服务器地址的有效性的方法
//定义类
class wechatCallbackapiTest
{
    public function valid()
    {
        //获取微信服务器GET请求的参数
        $echoStr = $_GET["echostr"];
        if($this->checkSignature()){
            echo $echoStr;
            exit;
        }
    }

    public function responseMsg()
    {
        //post数据,可能是由于不同的环境
        $postStr = $GLOBALS["HTTP_RAW_POST_DATA"];//①

        //提取post数据
        if (!empty($postStr)){
                libxml_disable_entity_loader(true);//②
                //得到了数据之后,然后我们就是要解析微信服务器发送过来的xml数据包了
                $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!');
        }
        //获取微信服务器GET请求的参数
        $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 );//④
        //开发者获得加密后的字符串可与signature对比,标识该请求来源于微信
        if( $tmpStr == $signature ){
            return true;
        }else{
            return false;
        }
    }
}

?>

1.$GLOBALS[‘HTTP_RAW_POST_DATA’]

$_POST:通过 HTTP POST 方法传递的变量组成的数组。是自动全局变量。
$GLOBALS[‘HTTP_RAW_POST_DATA’] :总是产生 $HTTP_RAW_POST_DATA
变量包含有原始的 POST 数据。此变量仅在碰到未识别 MIME 类型的数据时产生。
$HTTP_RAW_POST_DATA
对于 enctype=”multipart/form-data” 表单数据不可用。
也就是说基本上$GLOBALS[‘HTTP_RAW_POST_DATA’] 和 $_POST是一样的。
但是如果post过来的数据不是PHP能够识别的,你可以用 $GLOBALS[‘HTTP_RAW_POST_DATA’]来接收,比如 text/xml 或者 soap 等等。

在$GLOBALS [“HTTP_RAW_POST_DATA”]取不到值的情况下可以按以下方式排查:
1.用file_get_contents(‘php://input’)获取数据。
如果获取不到,则可能是数据传输错误,对请求进行捉包,分析数据。
2.如果file_get_contents(‘php://input’)有数据。则查看php.ini配置文件。
找到如下,如果没开启则开启
always_populate_raw_post_data = On(php7.0已经移除了此功能)

2.libxml_disable_entity_loader(true)

做安全防御用的:禁用加载外部实体。

3.sort($tmpArr, SORT_STRING);

其中参数SORT_STRING把每一项作为字符串来处理(数组升序排列)

4.sha1()

计算字符串的 SHA-1 散列(哈希加密).

本文标签: 入口文件PHP