文档:
1.微信根据code获取access_token;
2.微信自身获取access_token和openid;
3.根据access_token和openid获取用户信息;
4.微信分享获取的数据包;(主要是签名算法)
<?php
namespace app\common\lib\wx;
use app\common\lib\Redis;
use app\common\lib\Show;
use Curl\Curl;
class WX
{
protected $appid;
protected $appsecret;
public $Curl;
public $Redis;
public function __construct()
{
$this->appid = config('wx.AppID');
$this->appsecret = config('wx.AppSecret');
$this->Curl = new Curl();
$this->Redis = new Redis();
}
/**
* 根据code获取accesstoken和openid
* @param $code
* @return mixed
* @throws \Exception
*/
public function getAccessToken($code)
{
$data = array(
'appid'=>$this->appid,
'appsecret'=>$this->appsecret,
'grant_type'=>'authorization_code',
'code' => $code
);
$url = " https://api.weixin.qq.com/sns/oauth2/access_token";
$res = $this->Curl->get($url,$data);
$res = json_decode($res,true);
if ($res['errcode'])
{
throw new \Exception($res['errmsg']);
}
return $res;
}
/**
* 根据openid和access_token获取用户信息
* @param $accessToken
* @param $openid
* @return mixed
* @throws \Exception
*/
public function getInfoByAccessToken($accessToken,$openid)
{
$data = array(
'access_token'=>$accessToken,
'openid'=>$openid,
'lang'=>'zh_CN',
);
$url = " https://api.weixin.qq.com/sns/userinfo";
$res = $this->Curl->get($url,$data);
$res = json_decode($res,true);
if ($res['errcode'])
{
throw new \Exception($res['errmsg']);
}
return $res;
}
/**
* 设置noncestr(随机字符串)
* @param int $length
* @return string
*/
public function createNonceStr($length = 16) {
$chars = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
$str = "";
for ($i = 0; $i < $length; $i++) {
$str .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
}
return $str;
}
/**
* 获取access_token,有效期7200秒
* @param $access_token
* @return bool|string|\think\response\Json
*/
public function getSelfAccessToken()
{
$access_token = $this->Redis->get("access_token");
if (!$access_token) {
$access_token_url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=" . config('wx.AppID') . "&secret=" . config("wx.AppSecret");
$access_token_data = json_decode($this->Curl->get($access_token_url),true);
if ($access_token_data['errcode'] || !$access_token_data) {
return Show::error("未获取access_token");
}
$access_token = $access_token_data['access_token'];
$this->Redis->set("access_token",$access_token,"7000");
}
return $access_token;
}
/**
* 获得jsapi_ticket,有效期7200秒
* @param $access_token
* @return bool|string|\think\response\Json
*/
public function getJsApiTicket($access_token)
{
$jsapi_ticket = $this->Redis->get("jsapi_ticket");
if (!$jsapi_ticket){
$jsapi_ticket_url = "https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token=".$access_token."&type=jsapi";
$jsapi_ticket_data = json_decode($this->Curl->get($jsapi_ticket_url),true);
if ($jsapi_ticket_data['errcode'] !=0){
return Show::error("未获取jsapi_ticket");
}
$jsapi_ticket = $jsapi_ticket_data['ticket'];
$this->Redis->set("jsapi_ticket",$jsapi_ticket,"7000");
}
return $jsapi_ticket;
}
/**
* 签名算法
* @return array
*/
public function getSignPackage()
{
//获取access_token,有效期7200秒
$access_token = $this->getSelfAccessToken();
//获得jsapi_ticket,有效期7200秒
$jsapiTicket = $this->getJsApiTicket($access_token);
$nonceStr = $this->createNonceStr();
// 注意 URL 一定要动态获取,不能 hardcode.
$protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
$url = "$protocol".$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI'];
$timestamp = time();
// 这里参数的顺序要按照 key 值 ASCII 码升序排序
$string = "jsapi_ticket=$jsapiTicket&noncestr=$nonceStr×tamp=$timestamp&url=$url";
$signature = sha1($string);
$signPackage = array(
"appId" => $this->appid,
"nonceStr" => $nonceStr,
"timestamp" => $timestamp,
"url" => $url,
"signature" => $signature,
"rawString" => $string
);
return $signPackage;
}
}