- 用thinkphp进行微信开发的整体设计思考
- http://www.2cto.com/weixin/201504/388423.html
-
因为项目中很多地方都涉及到微信接口的调用 比如很多前台模块需要用到 后台模块也有少许调用 其他模块也可能会需要调用 为了让他们都能很方便的直接调用 我把他们独立成为一个模块 这个模块包含了基础的微信接口和微信jssdk
具体的设计请参考下面 当然如果有更好的建议可以共同交流
我先建立了一个新的模块叫Weixin 并在其下面建立了控制器BaseController 也就是一个微信类
这个微信基类 我是这样定义的
12345678910111213141516171819202122232425262728<?php
/**
*微信开发的公共类(不含支付 如需要可自行加入)
*
*/
namespace Weixin\Controller;
use Think\Controller;
use Com\WechatAuth;
use Com\Jssdk;
class
BaseController
extends
Controller {
public
$appId;
public
$appSecret;
public
$WechatAuth;
public
$jssdk;
public
function _initialize(){
$config = F(
'DB_CONFIG_DATA'
);
//获取配置信息
if
(!$config){
$config = api(
'Config/lists'
);
F(
'DB_CONFIG_DATA'
,$config);
}
C($config);
//添加配置
$
this
->appId = C(
'WEIXIN_CONFIG.appId'
);
$
this
->appSecret = C(
'WEIXIN_CONFIG.appSecret'
);
$
this
->WechatAuth =
new
WechatAuth($
this
->appId,$
this
->appSecret);
$
this
->jssdk =
new
Jssdk($appId,$appSecret);
//调用微信Jssdk
// $this->signPackage = $this->jssdk->GetSignPackage();
}
?>
下面是我微信sdk包的部署目录结构供参考
这些部署好后 在任意模块中引入的方法是
1$Weixin =
new
\Weixin\Controller\BaseController();
下面我用实例来讲述如何使用
1,获取用户信息(不管微信用户是否关注了公众号 下面代码大部分为注释内容 其实很少)
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273public
function mytest () {
$Weixin =
new
\Weixin\Controller\BaseController();
$domain = C(
'WEB_DOMAIN'
);
$request_url = $_SERVER[
'REQUEST_URI'
];
$redirect_url = $domain.$request_url;
if
(!isset($_GET[
'code'
])){
header(
'Location: https://open.weixin.qq.com/connect/oauth2/authorize?appid='
.$Weixin->appId.
'&redirect_uri='
.$redirect_url.
'&response_type=code&scope=snsapi_base&state=1/'
);
exit;
}
$code = $_GET[
'code'
];
$access_token_arr = $Weixin->WechatAuth ->getAccessToken(
'code'
,$code);
//oauth2.0网页授权的access_token
//$access_token_arr数据结构如下
/* Array
(
[access_token] => OezXcEiiBSKSxW0eoylIeLrIQT6NoDaXZIUcW_1wOj_TwSQ_Jqp2CBj0RLBbgvBCkzyZ74E6066btMwNPj6JYaR_TPn9PH02FgR4APr7iOhihlYgosPEyDZIVJXduuvUj3ay5cVYpv_TDA3TBNvLiA
[expires_in] => 7200
[refresh_token] => OezXcEiiBSKSxW0eoylIeLrIQT6NoDaXZIUcW_1wOj_TwSQ_Jqp2CBj0RLBbgvBCzJ6lw18Bb-cy9yUp2Tojmp48u_95jVHl1WTODEM0Z3yAPY8sORIlF0Gw8_99eEXsCagdc29djCjEWv2TovkPig
[openid] => o0r2njtFSolnsaBoVP5MxjhNjUlg
[scope] => snsapi_base
)*/
$globals_access_token = $Weixin->WechatAuth->getAccessToken();
//全局access_token
$userInfo = $Weixin->WechatAuth->userInfo($access_token_arr[
'openid'
]);
//通过全局access_token获取用户基本信息 未关注是array('subscribe'=>0,'openid')
if
(!$userInfo[
'subscribe'
]){
//用户未关注 只能通过网页授权api获取用户信息
$data = array();
$data[
'access_token'
] = $access_token_arr[
'access_token'
];
$data[
'openid'
] = $access_token_arr[
'openid'
];
$userinfo = $Weixin->WechatAuth->getUserInfo($data);
p($userinfo);
//打印信息
/*
Array(
[openid] => o0r2njtFSolnsaBoVP5MxjhNjUlg
[nickname] => 呼啦啦
[sex] => 1
[language] => zh_CN
[city] =>
[province] =>
[country] => 赞比亚
[headimgurl] => http://wx.qlogo.cn/mmopen/rBgkzASpGRQLPXPDlEGmPoHl35qjwaA8s4WfOncETZm7kDGEVicEJZORzO73m7ib9Av7AK7icLrfl1nmhxGsglmzJRcnryNPy6T/0
[privilege] => Array
(
)
)
*/
}
else
{
//关注了公众号 直接返回用户信息
p($userInfo);
//打印信息
/*
Array(
[subscribe] => 1
[openid] => o0r2njtFSolnsaBoVP5MxjhNjUlg
[nickname] => 呼啦啦
[sex] => 1
[language] => zh_CN
[city] =>
[province] =>
[country] => 赞比亚
[headimgurl] => http://wx.qlogo.cn/mmopen/rBgkzASpGRQLPXPDlEGmPoHl35qjwaA8s4WfOncETZm7kDGEVicEJZORzO73m7ib9Av7AK7icLrfl1nmhxGsglmzJRcnryNPy6T/0
[subscribe_time] => 1427793013
[remark] =>
)
*/
}
}
由于微信开发自身机制的原因,在这里要说明的是,thinkphp官方给的wechatAuth包 中并没有对access_token进行缓存,还需要进行适当修改 下面仅以wechatAuth.class.php文件修改为例说明 (网页授权的token, jssdk中的ticket 也要做类似如下的缓存,在此就不一一说明了)
1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677/**
* 构造方法,调用微信高级接口时实例化SDK
* @param string $appid 微信appid
* @param string $secret 微信appsecret
* @param string $token 获取到的access_token
*/
public
function __construct($appid, $secret, $token =
null
){
if
($appid && $secret){
$
this
->appId = $appid;
$
this
->appSecret = $secret;
if
(!empty($token)){
$
this
->accessToken = $token;
}
else
{
$
this
->getAccessToken();
}
}
else
{
throw
new
\Exception(
'参数错误!'
);
}
}
/**
* 获取access_token,用于后续接口访问
* @return array access_token信息,包含 token 和有效期
*/
public
function getAccessToken($type =
'client'
, $code =
null
){
$param = array(
'appid'
=> $
this
->appId,
'secret'
=> $
this
->appSecret
);
switch
($type) {
case
'client'
:
if
(S(
'globals_access_token'
)){
$
this
->accessToken = S(
'globals_access_token'
);
return
S(
'globals_access_token'
);
break
;
}
$param[
'grant_type'
] =
'client_credential'
;
$url =
"{$this->apiURL}/token"
;
break
;
case
'code'
:
$param[
'code'
] = $code;
$param[
'grant_type'
] =
'authorization_code'
;
$url =
"{$this->oauthApiURL}/oauth2/access_token"
;
break
;
default
:
throw
new
\Exception(
'不支持的grant_type类型'
);
break
;
}
$token = self::http($url, $param);
$token = json_decode($token,
true
);
if
(is_array($token)){
if
(isset($token[
'errcode'
])){
throw
new
\Exception($token[
'errmsg'
]);
}
else
{
if
($type ==
'client'
){
S(
'globals_access_token'
,$token[
'access_token'
],
7000
);
}
$
this
->accessToken = $token[
'access_token'
];
return
$token;
}
}
else
{
throw
new
\Exception(
'获取微信access_token失败!'
);
}
}