zoukankan      html  css  js  c++  java
  • 微信接口基本类 与连接

    <?php
    
    /**
     * 微信公众平台操作类
     */
    class WeChat {
    
    	private $_appid;
    	private $_appsecret;
    	private $_token;// 公众平台请求开发者时需要标记
    
    	//表示QRCode的类型
    	const QRCODE_TYPE_TEMP = 1;
    	const QRCODE_TYPE_LIMIT = 2;
    	const QRCODE_TYPE_LIMIT_STR = 3;
    
    	private $_msg_template = array(
    		'text' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[text]]></MsgType><Content><![CDATA[%s]]></Content></xml>',//文本回复XML模板
    		'image' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[image]]></MsgType><Image><MediaId><![CDATA[%s]]></MediaId></Image></xml>',//图片回复XML模板
    		'music' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[music]]></MsgType><Music><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><MusicUrl><![CDATA[%s]]></MusicUrl><HQMusicUrl><![CDATA[%s]]></HQMusicUrl><ThumbMediaId><![CDATA[%s]]></ThumbMediaId></Music></xml>',//音乐模板
    		'news' => '<xml><ToUserName><![CDATA[%s]]></ToUserName><FromUserName><![CDATA[%s]]></FromUserName><CreateTime>%s</CreateTime><MsgType><![CDATA[news]]></MsgType><ArticleCount>%s</ArticleCount><Articles>%s</Articles></xml>',// 新闻主体
    		'news_item' => '<item><Title><![CDATA[%s]]></Title><Description><![CDATA[%s]]></Description><PicUrl><![CDATA[%s]]></PicUrl><Url><![CDATA[%s]]></Url></item>',//某个新闻模板
    		);
    
    	public function __construct($id, $secret, $token) {
    		$this->_appid = $id;
    		$this->_appsecret = $secret;
    		$this->_token = $token;
    	}
    
    	/**
    	 * 设置菜单
    	 */
    	public function menuSet($menu) {
    		$url = 'https://api.weixin.qq.com/cgi-bin/menu/create?access_token=' . $this->_getAccessToken();
    		$data = $menu;
    		$result = $this->_requestPost($url, $data);
    		if ($result_obj->errcode == 0) {
    			return true;
    		} else {
    			echo $result_obj->errmsg, '<br>';
    			return false;
    		}
    	}
    
    	/**
    	 * 菜单删除
    	 */
    	public function menuDelete() {
    		$url = 'https://api.weixin.qq.com/cgi-bin/menu/delete?access_token=' . $this->_getAccessToken();
    		$result = $this->_requestGet($url);
    		$result_obj = json_decode($result);
    		if ($result_obj->errcode == 0) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    
    
    	public function responseMSG() {
    		// 获取请求时POST:XML字符串
    		// $_POST,不是key/value型因此不能使用该数组
    		$xml_str = $GLOBALS['HTTP_RAW_POST_DATA'];
    
    		// 如果没有post数据,则响应空字符串表示结束
    		if (empty($xml_str)) {
    			die ('');
    		}
    
    		// 解析该xml字符串,利用simpleXML
    		libxml_disable_entity_loader(true);//禁止xml实体解析,防止xml注入
          	$request_xml = simplexml_load_string($xml_str, 'SimpleXMLElement', LIBXML_NOCDATA);//从字符串获取simpleXML对象
    
          	// 判断该消息的类型通过元素:MsgType
          	switch ($request_xml->MsgType) {
          		case 'event': // 事件类型
          			// 判断具体的事件类型(关注,取消,点击)
          			$event = $request_xml->Event;
          			if ('subscribe'==$event) { // 关注事件
          				$this->_doSubscribe($request_xml);
          			}
          			elseif ('CLICK' == $event) { //菜单点击事件
          				$this->_doClick($request_xml);
          			}
          			elseif ('VIEW' == $event) { //连接跳转事件
    					$this->_doView($request_xml);
          			}
          			break;
          		case 'text': // 文本消息
          			$this->_doText($request_xml);
          			break;
          		case 'image': // 图片消息
          			$this->_doImage($request_xml);
          			break;
          		case 'voice': // 语音消息
          			$this->_doVoice($request_xml);
          			break;
          		case 'video': // 视频消息
          			$this->_doVideo($request_xml);
          			break;
          		case 'shortvideo': // 短视频消息
          			$this->_doShortVideo($request_xml);
          			break;
          		case 'location': // 位置消息
          			$this->_doLocation($request_xml);
          			break;
          		case 'link': // 连接消息
          			$this->_doLink($request_xml);
          			break;
          		default:
          			# code...
          			break;
          	}
    	}
    	private function _doClick($request_xml) {
    		$content = '你点击了菜单,携带的KEY为: ' . $request_xml->EventKey;
    		$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
    	}
    	/**
    	 * 用于处理文本消息的方法
    	 */
    	private function _doText($request_xml) {
    		// 获取文本内容
    		$content = $request_xml->Content;
    		// 对内容进行判断
    		if ('?' == $content) {
    			// 显示帮助信息
    			$response_content = '输入对应序号或名称,获取相应资源' . "
    " . '[1]PHP'."
    ". '[2]Java' . "
    " . '[3]C++';
    			// 将处理好的响应数据回复给用户
    			$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content);
    		} elseif ('1' == strtolower($content) || 'php'==strtolower($content)) {
    			$response_content = 'PHP工程师培训: ' . "
    " . 'http://php.itcast.cn/';
    			// 将处理好的响应数据回复给用户
    			$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content);
    		}
     		elseif ('2' == strtolower($content) || 'java'==strtolower($content)) {
    			$response_content = 'Java工程师培训: ' . "
    " . 'http://java.itcast.cn/';
    			// 将处理好的响应数据回复给用户
    			$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content);
    		}
     		elseif ('3' == strtolower($content) || 'c++'==strtolower($content)) {
    			$response_content = 'C++工程师培训: ' . "
    " . 'http://c.itcast.cn/';
    			// 将处理好的响应数据回复给用户
    			$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $response_content);
    		}
    		elseif ('图片' == $content) {
    			$id_list = array(
    				'eLrmGKbhf5kS86A9bqzkLS8-45sWvqBwUv4Q7XDd-oAds44Ad9hxq9h-ShmRQLyJ',
    				'0Fnq-gYU8zDugqxjPNywkhW5KSHXT6DdF-NGovaPfKry8grmheEVdEkdeY8qjZ--');
    			$rand_index = mt_rand(0, count($id_list)-1);
    			// 具体那张图片,应该由业务逻辑决定
    
    			$this->_msgImage($request_xml->FromUserName, $request_xml->ToUserName, $id_list[$rand_index], true);
    		}
    		elseif ('音乐' == $content) {
    			$music_url = 'http://weixin.fortheday.cn/dnaw.mp3';
    			$ha_music_url = 'http://weixin.fortheday.cn/dnaw.mp3';
    			$thumb_media_id = '0Fnq-gYU8zDugqxjPNywkhW5KSHXT6DdF-NGovaPfKry8grmheEVdEkdeY8qjZ--';
    			$title = '等你爱我';
    			$desc = '等你爱我-等到地老天荒';
    			$this->_msgMusic($request_xml->FromUserName, $request_xml->ToUserName, $music_url, $hq_music_url, $thumb_media_id, $title, $desc);
    		}
    		elseif ('新闻' == $content) {
    			$item_list = array(
    				array('title'=>'其实你该用母亲的方式回报母亲', 'desc'=>'母亲节快乐', 'picurl'=>'http://weixin.fortheday.cn/1.jpg', 'url'=>'http://www.soso.com/'),
    				array('title'=>'母亲节宠爱不手软,黄金秒杀豪礼特惠值到爆', 'desc'=>'母亲节快乐', 'picurl'=>'http://weixin.fortheday.cn/2.jpg', 'url'=>'http://www.soso.com/'),
    				array('title'=>'浅从财富管理视角看巴菲特思想', 'desc'=>'母亲节快乐', 'picurl'=>'http://weixin.fortheday.cn/3.jpg', 'url'=>'http://www.soso.com/'),
    				array('title'=>'广邀好友打气,赢取万元旅游金', 'desc'=>'母亲节快乐', 'picurl'=>'http://weixin.fortheday.cn/4.jpg', 'url'=>'http://www.soso.com/'),
    				);
    			$this->_msgNews($request_xml->FromUserName, $request_xml->ToUserName, $item_list);
    		}
    		else {
    			// 通过小黄鸡,响应给微信用户
    			$url = 'http://www.xiaohuangji.com/ajax.php';
    			$data['para'] = $content;
    			$response_content = $this->_requestPost($url, $data, false);
    		}
    	}
    
    	/**
    	 * 处理图片响应数据
    	 */
    	private function _doImage($request_xml) {
    		$content = '你所上传的图片的Media_ID:' . $request_xml->MediaId;
    		$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
    	}
    
    	private function _doLocation($request_xml) {
    		// $content = '你的坐标为,经度:'.$request_xml->Location_Y.',纬度:'.$request_xml->Location_X . "
    " . '你所在的位置为:' . $request_xml->Label;
    		// $this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
    		// 利用位置获取信息
    		//百度LBS圆形范围查询:
    		$url = 'http://api.map.baidu.com/place/v2/search?query=%s&location=%s&radius=%s&output=%s&ak=%s';
    		$query = '银行';
    		$location  = $request_xml->Location_X . ',' . $request_xml->Location_Y;
    		$radius = 2000;
    		$output = 'json';
    		$ak = 'OBDl6igKrng0V6VqT5RWIP6z';
    		$url = sprintf($url, urlencode($query), $location, $radius, $output, $ak);
    		$result = $this->_requestGet($url, false);
    		$result_obj = json_decode($result);
    		$re_list = array();
    		foreach($result_obj->results as $re) {
    			$r['name'] = $re->name;
    			$r['address'] = $re->address;
    			$re_list[] = implode('-', $r);
    		}
    		$re_str = implode("
    ", $re_list);
    		//
    		$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $re_str);
    	}
    	/**
    	 * 用于处理关注事件的方法
    	 * @param  [type] $request_xml 事件信息对象
    	 * @return [type]              [description]
    	 */
    	private function _doSubscribe($request_xml) {
    		// 利用消息发送,完成向关注用户打招呼功能!
    
    		$content = '感谢你关注,会向你发送优惠信息,请查收';
    		$this->_msgText($request_xml->FromUserName, $request_xml->ToUserName, $content);
    	}
    
    	/**
    	 * 发送文本信息
    	 * @param  [type] $to      目标用户ID
    	 * @param  [type] $from    来源用户ID
    	 * @param  [type] $content 内容
    	 * @return [type]          [description]
    	 */
    	private function _msgText($to, $from, $content) {
    		$response = sprintf($this->_msg_template['text'], $to, $from, time(), $content);
    		die($response);
    	}
    	/**
    	 * 发送图片消息
    	 * @param  [type] $to   [description]
    	 * @param  [type] $from [description]
    	 * @param  [type] $file 图片文件地址
    	 * @return [type]       [description]
    	 */
    	private function _msgImage($to, $from, $file, $is_id=false) {
    		if ($is_id) {
    			$media_id = $file;
    		} else {
    			// 上传图片到微信公众服务器,获取mediaID
    			$result_obj = $this->uploadTmp($file, 'image');
    			$media_id = $result_obj->media_id;
    		}
    		// 拼凑图像类消息xml文件
    		$response = sprintf($this->_msg_template['image'], $to, $from, time(), $media_id);
    		die($response);
    	}
    
    	/**
    	 * [_msgMusic description]
    	 * @param  [type] $to             [description]
    	 * @param  [type] $from           [description]
    	 * @param  [type] $music_url      [description]
    	 * @param  [type] $thumb_media_id [description]
    	 * @param  string $title          [description]
    	 * @param  string $desc           [description]
    	 * @return [type]                 [description]
    	 */
    	private function _msgMusic($to, $from, $music_url, $hq_music_url, $thumb_media_id, $title='', $desc='') {
    		$response = sprintf($this->_msg_template['music'], $to, $from, time(), $title, $desc, $music_url, $hq_music_url, $thumb_media_id);
    		die($response);
    	}
    
    	private function _msgNews($to, $from, $item_list=array()) {
    		// 拼凑文章部分
    		$item_str = '';
    		foreach($item_list as $item) {
    			$item_str .= sprintf($this->_msg_template['news_item'], $item['title'], $item['desc'], $item['picurl'], $item['url']);
    		}
    		//拼凑整体图文部分
    		$response = sprintf($this->_msg_template['news'], $to, $from, time(), count($item_list), $item_str);
    		die($response);
    	}
    
    	/**
    	 * 上传临时素材
    	 */
    	public function uploadTmp($file, $type) {
    		$url = 'https://api.weixin.qq.com/cgi-bin/media/upload?access_token='.$this->_getAccessToken() .'&type='.$type;
    
    		$data['media'] = '@'. $file;
    		$result = $this->_requestPost($url, $data);
    		$result_obj = json_decode($result);
    		return $result_obj;
    	}
    
    	/**
    	 * 用于第一次验证URL合法性
    	 */
    	public function firstValid() {
    		// 检验签名的合法性
    		if ($this->_checkSignature()) {
    			// 签名合法,告知微信公众平台服务器
    			echo $_GET['echostr'];
    		}
    	}
    	/**
    	 * 验证签名
    	 * @return bool [description]
    	 */
    	private function _checkSignature() {
    		// 获得由微信公众平台请求的验证数据
    		$signature = $_GET['signature'];
    		$timestamp = $_GET['timestamp'];
    		$nonce = $_GET['nonce'];
    		// 将时间戳,随机字符串,token按照字母顺序排序并连接
    		$tmp_arr = array($this->_token, $timestamp, $nonce);
    		sort($tmp_arr, SORT_STRING);// 字典顺序
    		$tmp_str = implode($tmp_arr);//连接
    		$tmp_str = sha1($tmp_str);// sha1签名
    
    		if ($signature == $tmp_str) {
    			return true;
    		} else {
    			return false;
    		}
    	}
    
    
    
    	/**
    	 * 获取 access_tonken
    	 * @param string $token_file 用来存储token的临时文件
    	 */
    	private function _getAccessToken($token_file='./access_token') {
    		// 考虑过期问题,将获取的access_token存储到某个文件中
    		$life_time = 7200;
    		if (file_exists($token_file) && time()-filemtime($token_file)<$life_time) {
    			// 存在有效的access_token
    			return file_get_contents($token_file);
    		}
    		// 目标URL:
    		$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$this->_appid}&secret={$this->_appsecret}";
    		//向该URL,发送GET请求
    		$result = $this->_requestGet($url);
    		if (!$result) {
    			return false;
    		}
    		// 存在返回响应结果
    		$result_obj = json_decode($result);
    		// 写入
    		file_put_contents($token_file, $result_obj->access_token);
    		return $result_obj->access_token;
    	}
    
    	/**
    	 * [getQRCodeTicket description]
    	 * @param $content 内容
    	 * @param $type qr码类型
    	 * @param $expire 有效期,如果是临时的类型则需要该参数
    	 * @return string ticket
    	 */
    	private function _getQRCodeTicket($content, $type=2, $expire=604800) {
    		$access_token = $this->_getAccessToken();
    		$url = "https://api.weixin.qq.com/cgi-bin/qrcode/create?access_token=$access_token";
    		$type_list = array(
    			self::QRCODE_TYPE_TEMP => 'QR_SCENE',
    			self::QRCODE_TYPE_LIMIT => 'QR_LIMIT_SCENE',
    			self::QRCODE_TYPE_LIMIT_STR => 'QR_LIMIT_STR_SCENE',
    			);
    		$action_name = $type_list[$type];
    		switch ($type) {
    			case self::QRCODE_TYPE_TEMP:
    			// {"expire_seconds": 604800, "action_name": "QR_SCENE", "action_info": {"scene": {"scene_id": 123}}}
    				$data_arr['expire_seconds'] = $expire;
    				$data_arr['action_name'] = $action_name;
    				$data_arr['action_info']['scene']['scene_id'] = $content;
    				break;
    			case self::QRCODE_TYPE_LIMIT:
    			case self::QRCODE_TYPE_LIMIT_STR:
    				$data_arr['action_name'] = $action_name;
    				$data_arr['action_info']['scene']['scene_id'] = $content;
    				break;
    		}
    		$data = json_encode($data_arr);
    		$result = $this->_requestPost($url, $data);
    		if (!$result) {
    			return false;
    		}
    		//处理响应数据
    		$result_obj = json_decode($result);
    		return $result_obj->ticket;
    	}
    	/**
    	 * [getQRCode description]
    	 * @param  int|string  $content qrcode内容标识
    	 * @param  [type]  $file    存储为文件的地址,如果为NULL表示直接输出
    	 * @param  integer $type    类型
    	 * @param  integer $expire  如果是临时,表示其有效期
    	 * @return [type]           [description]
    	 */
    	public function getQRCode($content, $file=NULL, $type=2, $expire=604800) {
    		// 获取ticket
    		$ticket = $this->_getQRCodeTicket($content, $type=2, $expire=604800);
    		$url = "https://mp.weixin.qq.com/cgi-bin/showqrcode?ticket=$ticket";
    		$result = $this->_requestGet($url);//此时result就是图像内容
    		if ($file) {
    			file_put_contents($file, $result);
    		} else {
    			header('Content-Type: image/jpeg');
    			echo $result;
    		}
    	}
    	private function _requestPost($url, $data, $ssl=true) {
    		// curl完成
    		$curl = curl_init();
    
    		//设置curl选项
    		curl_setopt($curl, CURLOPT_URL, $url);//URL
    		$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '
    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 FirePHP/0.7.4';
    		curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);//user_agent,请求代理信息
    		curl_setopt($curl, CURLOPT_AUTOREFERER, true);//referer头,请求来源
    		curl_setopt($curl, CURLOPT_TIMEOUT, 30);//设置超时时间
    		//SSL相关
    		if ($ssl) {
    			curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//禁用后cURL将终止从服务端进行验证
    			curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//检查服务器SSL证书中是否存在一个公用名(common name)。
    		}
    		// 处理post相关选项
    		curl_setopt($curl, CURLOPT_POST, true);// 是否为POST请求
    		curl_setopt($curl, CURLOPT_POSTFIELDS, $data);// 处理请求数据
    		// 处理响应结果
    		curl_setopt($curl, CURLOPT_HEADER, false);//是否处理响应头
    		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//curl_exec()是否返回响应结果
    
    		// 发出请求
    		$response = curl_exec($curl);
    		if (false === $response) {
    			echo '<br>', curl_error($curl), '<br>';
    			return false;
    		}
    		curl_close($curl);
    		return $response;
    	}
    
    	/**
    	 * 发送GET请求的方法
    	 * @param string $url URL
    	 * @param bool $ssl 是否为https协议
    	 * @return string 响应主体Content
    	 */
    	private function _requestGet($url, $ssl=true) {
    		// curl完成
    		$curl = curl_init();
    
    		//设置curl选项
    		curl_setopt($curl, CURLOPT_URL, $url);//URL
    		$user_agent = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : '
    Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Firefox/38.0 FirePHP/0.7.4';
    		curl_setopt($curl, CURLOPT_USERAGENT, $user_agent);//user_agent,请求代理信息
    		curl_setopt($curl, CURLOPT_AUTOREFERER, true);//referer头,请求来源
    		curl_setopt($curl, CURLOPT_TIMEOUT, 30);//设置超时时间
    
    		//SSL相关
    		if ($ssl) {
    			curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);//禁用后cURL将终止从服务端进行验证
    			curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2);//检查服务器SSL证书中是否存在一个公用名(common name)。
    		}
    		curl_setopt($curl, CURLOPT_HEADER, false);//是否处理响应头
    		curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);//curl_exec()是否返回响应结果
    
    		// 发出请求
    		$response = curl_exec($curl);
    		if (false === $response) {
    			echo '<br>', curl_error($curl), '<br>';
    			return false;
    		}
    		curl_close($curl);
    		return $response;
    	}
    
    }
    

      

    入口

    <?php
    
    header('Content-Type: text/html; charset=utf8');
    
    
    require './WeChat.class.php';
    define('APPID', 'wxe647b92b9dc39f1b');
    define('APPSECRET', 'e16374d53b5b78bf25fd7e29e3d58c46');
    define('TOKEN', 'itcast_php34');
    $wechat = new WeChat(APPID, APPSECRET, TOKEN);
    
    // 第一次验证:
    // $wechat->firstValid();
    //
    // 处理威信公众平台的的消息(事件)
    $wechat->responseMSG();
    

      

  • 相关阅读:
    Java的代理proxy机制
    Java 编译器 javac 笔记:javac API、注解处理 API 与 Lombok 原理
    Java 运行时获取方法参数名
    python 之 list 和 dict 置空
    Python 模块(Module)调用
    Python 模块(Module)及包
    Mybatis中进行批量更新(updateBatch)
    可持久化线段树+主席树+动态主席树
    无向图的割点与割边
    [NOIP2016] 愤怒的小鸟 题解
  • 原文地址:https://www.cnblogs.com/Czc963239044/p/7211755.html
Copyright © 2011-2022 走看看