微信开发绑定事件实现机制
define("TOKEN", "Your Token"); $test = new TestController(); $test->bind('subscribe'); $test->trigger(); class TestController{ public $wechat = null; public function __construct(){ $this->wechat = new Wechat(); } public function bind($event, $method=''){ $this->wechat->bind($event, $method); } public function trigger(){ $this->wechat->trigger($this); } public function onSubscribe(){ $request = $this->wechat->request; $fromUsername = $request->FromUserName; $toUsername = $request->ToUserName; $msgType = 'news'; $xml = $this->wechat->setXmlHeader($fromUsername, $toUsername, $msgType); $content = '<ArticleCount>1</ArticleCount> <Articles> <item> <Title><![CDATA[欢迎订阅]]></Title> <Description><![CDATA[hehehe]]></Description> <PicUrl><![CDATA[http://pic.58pic.com/58pic/11/88/62/74h58PICNWd.jpg]]></PicUrl> <Url><![CDATA[http://www.baidu.com]]></Url> </item> </Articles>'; $this->wechat->dispaly($xml, $content); } public function response(){ $this->test(); } public function test(){ if($this->wechat->request->Content != ''){ if(preg_match('/你是/', $this->wechat->request->Content)){ $this->wechat->p('我是你大哥呀!!!'); } $this->wechat->p('您发送了一条消息'); } } } class Wechat{ public $event = ''; public $bind = []; public $request = null; public function __construct(){ if(isset($_GET['echostr'])) $this->valid(); $this->request = $this->getRequest(); } public function valid(){ $echoStr = $_GET["echostr"]; if($this->__checkSignature()){ echo $echoStr; exit; } } public function bind($event, $method=''){ if(empty($method)) $method = "on" . ucfirst($event); $this->bind[$event] = $method; } public function trigger($object){ $method = isset($this->bind[$this->event])? $this->bind[$this->event] : 'response'; call_user_func_array([$object, $method], []); } public function getRequest(){ $postStr = $GLOBALS["HTTP_RAW_POST_DATA"]; if(!empty($postStr)){ libxml_disable_entity_loader(true); $postObj = simplexml_load_string($postStr, 'SimpleXMLElement', LIBXML_NOCDATA); $postObj->Content = trim($postObj->Content); $postObj->getTime = time(); if($postObj->MsgType == 'event') $this->event = (string) $postObj->Event; }else{ return null; } return $postObj; } public function setXmlHeader($fromUsername, $toUsername, $msgType){ $xml = '<xml> <ToUserName><![CDATA[%s]]></ToUserName> <FromUserName><![CDATA[%s]]></FromUserName> <CreateTime>%s</CreateTime> <MsgType><![CDATA[%s]]></MsgType> {{__content__}} </xml>'; $time = time(); return sprintf($xml, $fromUsername, $toUsername, $time, $msgType); } private function __checkSignature(){ // you must define TOKEN by yourself if (!defined("TOKEN")) { throw new Exception('TOKEN is not defined!'); } $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 ); if( $tmpStr == $signature ){ return true; }else{ return false; } } //调试方法 public function p($content){ $postObj = $this->request; $fromUsername = $postObj->FromUserName; $toUsername = $postObj->ToUserName; $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>"; $msgType = "text"; if(!is_scalar($content)) $content = var_export($content, true); if(empty($content)) $content = 'empty'; $resultStr = sprintf($textTpl, $fromUsername, $toUsername, time(), $msgType, $content); echo $resultStr; exit; } public function dispaly($xml, $content){ $xml = str_replace('{{__content__}}', $content, $xml); exit($xml); } }