由於項目中不少地方都涉及到微信接口的調用 好比不少前臺模塊須要用到 後臺模塊也有少量調用 其餘模塊也可能會須要調用 爲了讓他們都能很方便的直接調用 我把他們獨立成爲一個模塊 這個模塊包含了基礎的微信接口和微信jssdkphp
具體的設計請參考下面 固然若是有更好的建議能夠共同交流 java
我先創建了一個新的模塊叫Weixin 並在其下面創建了控制器BaseController 也就是一個微信類thinkphp
這個微信基類 我是這樣定義的json
<?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包的部署目錄結構供參考api
這些部署好後 在任意模塊中引入的方法是 緩存
$Weixin = new \Weixin\Controller\BaseController();
下面我用實例來說述如何使用微信
1,獲取用戶信息(無論微信用戶是否關注了公衆號 下面代碼大部分爲註釋內容 其實不多)數據結構
public 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 也要作相似以下的緩存,在此就不一一說明了)微信開發
/** * 構造方法,調用微信高級接口時實例化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失敗!'); } }