您的位置:首页 > 移动开发 > 微信开发

微信授权封装+微信系统告警通知

2017-04-07 10:39 295 查看
简要说明

本次主要说的是微信授权获取用户基本信息,还有就是日志反馈系统。利用微信自带的消息及时通知开发人员程序的报错。可达到快速收到问题解决问题,有助于建立一个可靠的风控体系

注意这里代码只有隐性授权 显性授权自己加上即可  原理一样

系统告警通知是使用的微信模板消息进行一个告警的通知

基本model   不同的框架稍微改改就可以直接用(如:缓存方法哪里需要自己根据自己框架特点进行改动)

<?php
/**
*微信推送消息
*by sqc
*
*/
defined('InShopNC') or exit('Access Invalid!');

class wx_centerModel extends Model{

protected $appid;
protected $secrect;
protected $accessToken;
protected $redirect_uri;// 微信授权回调地址
protected $code; // 微信授权code
protected $o_access_token; // 微信授权access_token 注意:此access_token与基础支持的access_token不同
protected $openid; // 微信授权openid
protected $unionid; // 微信授权unionid
//protected $GobackUrl; // 授权结束后返回用户界面的地址 弃
protected $errors;

function  __construct()
{
$this->appid = '********';
$this->secrect = '**************';

// 测试 121科技号
// $this->appid = '************';
// $this->secrect = '****************';
// 第三个参数可用于多个公众号分别存储access_token使得与主号分离
$this->accessToken = $this->getToken($this->appid, $this->secrect,'wx_access_token');
}

/**
* 设置参数
*
* @param mixed $key
* @param mixed $value
*/
public function set($key,$value){
$this->$key = $value;
}
/**
* 读取参数
*/
public function get($key){
return $this->$key;
}

/**
* 隐性授权第一步:获取code
* @return [type] [description]
*/
public function silent_outh_step1(){
var_dump($this->redirect_uri);
if($this->redirect_uri){
$url="https://open.weixin.qq.com/connect/oauth2/authorize?appid={$this->appid}&redirect_uri=".urlencode($this->redirect_uri)."&response_type=code&scope=snsapi_base&state=state#wechat_redirect";
header('Location:'.$url);
}else{
return $this->error('微信授权回调地址参数丢失');
}

}

/**
* 隐性授权第2步:获取openid等信息  注意,在未关注公众号时,用户访问公众号的网页,也会产生一个用户和公众号唯一的OpenID
* @return 对象
*/
public function silent_outh_step2(){
$this->code = $this->code?$this->code:$_GET['code'];
if($this->code){
//第二步:通过code换取网页授权access_token
$url = "https://api.weixin.qq.com/sns/oauth2/access_token?appid={$this->appid}&secret={$this->secrect}&code={$this->code}&grant_type=authorization_code";
$res_json = $this->request_get($url);
$res_arrone = json_decode($res_json, true); //转换为数组
if($res_arrone['openid']){
$this->openid = $res_arrone['openid'];
$this->o_access_token = $res_arrone['access_token'];
$this->unionid = $res_arrone['unionid'];// 这一步会有unionid 这是手册中没有的(2017.4.6)
}else{
$this->error($res_arrone);
}
}else{
$this->error('没有获取到微信授权code');
}
return $this;

}

/**
* 授权第3步:获取用户基本信息的  注意:这个是基于(这2个字省略了很多哦 可以到我博客上看)显性授权的
* 需scope为 snsapi_userinfo
* 如果网页授权作用域为snsapi_userinfo,则此时开发者可以通过access_token和openid拉取用户信息了
* @return [type] [description]
*/
public function outh_step3(){
if($this->openid && $this->o_access_token){
$get_userinfo_url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$this->o_access_token}&openid={$this->openid}&lang=zh_CN";
$userinfo_json = $this->request_get($get_userinfo_url);
$userinfo = json_decode($userinfo_json, true); //转换为数组
//判断授权是否成功
if(empty($userinfo) || isset($userinfo['errcode'])){
if(!$this->unionid){
return $this->error($userinfo);
}
$userinfo['unionid']=$this->unionid;
$userinfo['openid']=$this->openid;
}
return $userinfo;
}else{
return $this->error('获取用户信息参数不全');
}

}

/**
* 获取用户基本信息(UnionID机制)  基于openid
*/
public function get_user_info(){
if($this->accessToken && $this->openid){
$url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token={$this->accessToken}&openid={$this->openid}&lang=zh_CN";
$userinfo_json = $this->request_get($url);
$userinfo = json_decode($userinfo_json, true); //转换为数组
if(empty($userinfo) || isset($userinfo['errcode'])){
if(!$this->unionid){
$userinfo['get_user_info'] =1;// 与outh_step3做区分
return $this->error($userinfo);
}
$userinfo['unionid']=$this->unionid;
$userinfo['openid']=$this->openid;
}
return $userinfo;
}else{
return $this->error('accessToken或openid无法获取到');
}
}

/**
* 发送post请求
* @param string $url
* @param string $param
* @return bool|mixed
*/
protected function request_post($url = '', $param = '')
{
if (empty($url) || empty($param)) {
return false;
}
$postUrl = $url;
$curlPost = $param;
$ch = curl_init(); //初始化curl
curl_setopt($ch, CURLOPT_URL, $postUrl); //抓取指定网页
curl_setopt($ch, CURLOPT_HEADER, 0); //设置header
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //要求结果为字符串且输出到屏幕上
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_POST, 1); //post提交方式
curl_setopt($ch, CURLOPT_POSTFIELDS, $curlPost);
$data = curl_exec($ch); //运行curl
curl_close($ch);
return $data;
}
/**
* 发送get请求
* @param string $url
* @return bool|mixed
*/
protected function request_get($url = '')
{
if (empty($url)) {
return false;
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, 500);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
return $data;
}
/**
* @param $appid
* @param $appsecret
* @return mixed
* 获取token
*/
public function getToken($appid, $appsecret,$name)
{
$key =  $name?$name:$appid;
$access_token_info = rkcache($key);
$access_token_info = unserialize($access_token_info);
if ($access_token_info['time']>TIMESTAMP) {
$access_token = $access_token_info['token'];
} else {
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . $appid . "&secret=" . $appsecret;
$token = $this->request_get($url);
$token = json_decode(stripslashes($token));
$arr = json_decode(json_encode($token), true);
$access_token = $arr['access_token'];
$cache_arr['token'] = $arr['access_token'];
$cache_arr['time'] = TIMESTAMP + 7200;
wkcache($key, serialize($cache_arr));
}
return $access_token;
}

/**
* 制作一个日志
* @param  string $name 错误标题
* @param  mid  $msg  错误描述 可以字符串 或 数组 数组只支持到2维
* @param  string $type 错误级别
*
*/
public function make_log($name,$msg,$type='notice',$openid=''){
$template_id ='DjyGuUbytYLKvEyQUxRRffsHIWYuErqrijovg6LZVd8';

if(is_array($msg)){
$tmp_msg = '';
foreach ($msg as $k => $v) {
$tmp_msg .=$k.':'.$v;
if(is_array($v)){
$tmp_msg .=' ( ';
foreach ($v as $k2 => $v2) {
$tmp_msg .=$k2.'->'.$v2;
}
$tmp_msg .=' ) ';
}
$tmp_msg .='|||';
}
$msg = $tmp_msg;
}

c5b6
$data=array(
'first'=>array('value'=>urlencode("商城组错误通知"),'color'=>"#00CD00"),
'keyword1'=>array('value'=>urlencode($name),'color'=>'#EE5C42'),
'keyword2'=>array('value'=>urlencode(date('Y-m-d H:i:s',TIMESTAMP)),'color'=>'#030303'),
'keyword3'=>array('value'=>urlencode($type),'color'=>'#EE9A00'),
'keyword4'=>array('value'=>urlencode($this->getClientIP()),'color'=>'#030303'),
'keyword5'=>array('value'=>urlencode($msg),'color'=>'#EE4000'),
'remark'=>array('value'=>urlencode('121商城组'),'color'=>'#030303'),
);
if(!$openid){
$log_m = Model('wx_log');
$openids = $log_m->select();
foreach ($openids as $ky => $ve) {
if($ve['openid']){
$this->doSend_logInfo($ve['openid'],$template_id,'',$data);
}
}
return true;
}
$wxmsgs = $this->doSend_logInfo($openid,$template_id,'',$data);
}
/**
* 发送自定义的模板消息
* @param $touser
* @param $template_id
* @param $url
* @param $data
* @param string $topcolor
* @return bool
*/
public function doSend_logInfo($touser, $template_id, $url, $data, $topcolor = '#7B68EE')
{
$template = array(
'touser' => $touser,
'template_id' => $template_id,
'url' => $url,
'topcolor' => $topcolor,
'data' => $data
);
$json_template = json_encode($template);
$url = "https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=" . $this->accessToken;
$dataRes = $this->request_post($url, urldecode($json_template));
$dataRes = json_decode(stripslashes($dataRes));
$dataRes = json_decode(json_encode($dataRes), true);
if ($dataRes['errcode'] == 0) {
return true;
} else {
return false;
}
}

private function getClientIP(){
if (getenv("HTTP_CLIENT_IP"))
$ip = getenv("HTTP_CLIENT_IP");
else if(getenv("HTTP_X_FORWARDED_FOR"))
$ip = getenv("HTTP_X_FORWARDED_FOR");
else if(getenv("REMOTE_ADDR"))
$ip = getenv("REMOTE_ADDR");
else $ip = "Unknow";
return $ip;
}
/**
* 返回用户错误信息
* @return 返回值可以是josn或者是array
*/
private function error($msg,$type = 'array'){
switch ($type) {
case 'array':
$this->errors['error'][] = $msg;
$this->make_log('微信授权系统',$msg,'notice');
return $this->errors;
break;

default:
# code...
break;
}
}
}

控制器总的授权调用

第一步
public function indexOp() {
if(empty($_COOKIE['unionid'])){
// 授权获取用户的unionid
$this->check_back_url();
// 开始调用授权
$wx_model = Model('wx_center');
$wx_model->set('redirect_uri',BASE_SITE_URL."/mobile/index.php?act=goods_wx&op=get_unionid");
$wx_model->silent_outh_step1();
}else{

// 直接返回
header('Location: '.$this->check_back_url());

}
}
第二步  $re = $wx_model->silent_outh_step2()->get_user_info(); 就是返回用户的基本信息
/**
* 微信获取用户的信息
*/
public function get_unionidOp() {
$wx_model = Model('wx_center');
$wx_model->set('code',$_GET['code']);
$re = $wx_model->silent_outh_step2()->get_user_info();
if(empty($re)||!$re['unionid']){
echo '<meta charset="utf-8">';
die('<center><h1>抱歉,您的网络超时,请稍后重试</h1></center>');
}
$_SESSION['my_userinfo'] = $re;
setcookie("unionid",$re['unionid'],time()+365*3600*12,'/');
header('Location: '.htmlspecialchars_decode(urldecode($_COOKIE['GobackUrl'])));die;

}



告警消息的发送demo

$join_ceshi['商城告警测试'] = '成功成功';
$join_ceshi['登陆错误'] = '10分钟多个注册导致系统故障';
$join_ceshi['订单告警'] = '10分钟内10000个下单';
$join_ceshi['下单错误'] = '参数错误';
$wx_model->make_log('这是一条测试数据',$join_ceshi,'notice',$re['openid']);


这个是我自己框架中model的调用 (逻辑处理model 类似于ThinkPHP中的大D方法)
$wx_model = Model('wx_center');
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息