zoukankan      html  css  js  c++  java
  • 【玩转微信公众平台之八】 演示样例代码分析

    目測这篇文章会非常长...

    -----------------
    还记得我们之前从微信公众平台下载的那个演示样例代码“Wx-sample.zip”吗?解压后是一个wx_sample.php文档。没错,本篇接下来就是解释下这个文档里的代码都是啥意思。首先浏览下所有代码。事实上也就80行左右,少的可怜:
    <?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)){
                    
                  	$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()
    	{
            $signature = $_GET["signature"];
            $timestamp = $_GET["timestamp"];
            $nonce = $_GET["nonce"];	
            		
    		$token = TOKEN;
    		$tmpArr = array($token, $timestamp, $nonce);
    		sort($tmpArr, SORT_STRING);
    		$tmpStr = implode( $tmpArr );
    		$tmpStr = sha1( $tmpStr );
    		
    		if( $tmpStr == $signature ){
    			return true;
    		}else{
    			return false;
    		}
    	}
    }
    
    ?>

    1、先看第7行,它提前定义了常量 TOKEN 的值为 “weixin”,假设你有印象的话会发现,这个TOKEN就是我们在申请成为开发人员时填写的TOKEN


    2、第8、9两行代码先跳过不看,直接从11行開始。
    11行定义了一个类,类名为wechatCallbackapiTest。这个类中有三个个函数,一个函数叫valid(),它的作用是签名和接口验证。还有一个函数叫responseMsg(),这个函数最重要,先记着。最后一个函数是checkSignature(),它是一段签名验证程序。


    好吧,我想有些刚開始学习的人可能对类,函数这些概念比較模糊,所以我用了一段“白话文”来翻译下:
    11行制造了一个手机,手机名为wechatCallbackapiTest,这个手机有三个功能。一个功能是valid(),它的作用是签名和接口验证。还有一个函数叫responseMsg(),这个该手机最重要的功能,就跟打电话一样;最后一个功能是checkSignature(),它是用来验证签名的。


    3、首先看13行的valid()函数:在15行从微信后台获取一耳光随机字符赋予变量 $echoStr,18-20行訪问61行的checkSignature()函数的签名验证方法,假设签名一致,输出变量$echoStr,完整验证配置接口的操作。


    4、既然上面都说到checkSignature(),那我就先解释下checkSignature()的原理。


    微信后台在发送数据给公众账号server时,会额外带上3个參数:signature、timestamp、nonce。当中timestamp是时间戳,nonce是一个随机数,signature是对timestamp、nonce和Token进行SHA1(安全哈希算法)加密后的字符串。


    在公众账号server收到timestamp、nonce和signature之后,相同对nonce、timastamp和Token使用SHA1加密算法。得到自己的签名,假设自己的签名和请求中的signature是一样的。那么说明请求是来自微信后台而不是恶意第三方。

    以下看下checkSignature()的代码+凝视:

    private function checkSignature()
    {
    	//获取GET參数
    	$signature = $_GET["signature"];
    	$timestamp = $_GET["timestamp"];
    	$nonce = $_GET["nonce"];	
    			
    	$token = TOKEN;
    	//把nonce、timestamp、TOKEN组装到数组里并做排序
    	$tmpArr = array($token, $timestamp, $nonce);
    	sort($tmpArr, SORT_STRING);//排序
    	//将数组中的元素合成字符串
    	$tmpStr = implode( $tmpArr );
    	//sha1加密
    	$tmpStr = sha1( $tmpStr );
    	
    	//推断加密后的字符串是否和signature相等
    	if( $tmpStr == $signature ){
    		return true;
    	}else{
    		return false;
    	}
    }
    

    5、真够累的。以下看responseMsg这个函数。它但是我们回复微信的关键,以后实现微信的各种功能也都是在这里实现的。还是来段代码+凝视吧,这样写起来比較轻松。
    public function responseMsg()
    {
    	//这里获取用户发来的数据。并保存到$postStr变量中,由于微信后台发送的数据是XML格式的数据,
    	//所以须要$GLOBALS["HTTP_RAW_POST_DATA"] 方法来获取。
    	$postStr = $GLOBALS["HTTP_RAW_POST_DATA"];
    
    
    	//假设用户端发来的数据不为空。则运行以下这段代码
    	if (!empty($postStr)){
    			//用simplexml_load_string解析XML数据,并放入$postObj变量中
    			$postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA);
    			$fromUsername = $postObj->FromUserName;//获得usernameOpenID,
    			$toUsername = $postObj->ToUserName;//获得你的微信公众账号ID
    			$keyword = trim($postObj->Content);//获得用户发给你的文本内容。trim是去掉文本中的空格
    			$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";//设置回复消息的类型为text类型。即文本类型
    				$contentStr = "Welcome to wechat world!";//回复的内容放到$contentStr变量中
    				//以下这行是将用户ID,我们微信公众账号ID。系统时间,回复消息类型。回复内容 打包到$textTpl变量中,
    				$resultStr = sprintf($textTpl, $fromUsername, $toUsername, $time, $msgType, $contentStr);
    				echo $resultStr;//输出回复的信息。即发送微信给微信后台,后台再将消息发给用户。

    }else{ echo "Input something..."; } }else { echo ""; exit; } }


    呼,最终写完了。我知道写的还是非常潦草。但个人理解也仅仅是到这样的程度,见谅。假设还不是非常理解也没事,由于以后在功能开发过程中常常会与它们打交道,用多了也就理解了。

    尊重原创,转载请注明来源:http://blog.csdn.net/star530/article/details/25836919
  • 相关阅读:
    SolrCloud阶段总结
    Solr总结
    机器学习算法与Python实践之(六)二分k均值聚类
    机器学习问题方法总结
    浅谈Kmeans聚类
    AVL树的算法思路整理
    Solr4.6从数据库导数据的步骤
    红黑树
    浅谈 Adaboost 算法
    POJ 1836 Alignment
  • 原文地址:https://www.cnblogs.com/mqxnongmin/p/10889892.html
Copyright © 2011-2022 走看看