微信开发中有时会频繁调用access_token和jsapi_ticket数据
而access_token和jsapi_ticket在微信服务器中有调用限制,
如何多快、好省的缓存使用access_token和jsapi_ticket的值,下面介绍三种可行方案:
一、用PHP memcache方案缓存access_token和jsapi_ticket值
1.签名的生成
/**
* 获取签名
*/
public static function getSign($params, $key)
{
ksort($params, SORT_STRING); //对所有待签名参数按照字段名的ASCII 码从小到大排序(字典序)
$unSignParaString = self::formatQueryParaMap($params, false); //排序编码处理
$signStr = strtoupper(md5($unSignParaString . "&key=" . $key));//md5加密 形成签名
return $signStr;
}
protected static function formatQueryParaMap($paraMap, $urlEncode = false)
{
$buff = "";
ksort($paraMap);
foreach ($paraMap as $k => $v) {
if (null != $v && "null" != $v) {
if ($urlEncode) {
$v = urlencode($v); //url 编码后便宜传递
}
$buff .= $k . "=" . $v . "&";
}
}
$reqPar = '';
if (strlen($buff) > 0) {
$reqPar = substr($buff, 0, strlen($buff) - 1);
}
return $reqPar;
}
2.access_token和jsapi_ticket缓存后长时间有效,memcache方案
memcache使用很简单,可以参考php的文档说明。这里主要说说超时问题。
最开始使用set(key,value,7200), 来设置缓存的有效时间为7200秒,意味着access_token/jsapi_ticket失效时,缓存中的值也失效,无法get出来,这是就会自动向微信服务器请求,代码如下:
public function getAccess()
{
$appid = $this->appid;
$appsecret = $this->appsecret;
$url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appsecret";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$output = curl_exec($ch);
curl_close($ch);
$jsoninfo = json_decode($output, true);
$access_token = $jsoninfo["access_token"];
$memcache_obj = memcache_connect("localhost", 11211);
/* 面向对象编程 API */
//$memcache_obj->add('var_key', 'test variable', false, 10);
//$var1=$memcache_obj->get('var_key');
$memcache_obj->set('access_token', $access_token, MEMCACHE_COMPRESSED, 7200);
//$var2=$memcache_obj->get('var_key');
return $access_token;
//return $jsoninfo['errmsg'];
}
//获取get_access_token_cache
public function get_access_token_cache(){
$memcache_obj = memcache_connect("localhost", 11211);
$var=$memcache_obj->get('access_token'); //获取缓存数据
return ($var)?$var:self::getAccess(); //如果缓存未过期取缓存数据,如果过期重新获取
}
二、 Mysql方案
新建一个数据表,存储 access_token和jsapi_ticket,及其对应的获取时间,取用时检测是否超时,若超时则重新向服务器请求,更新数据库的值。实现的逻辑与缓存类似。
header("Content-type:text/html; Charset=utf-8");
$token_obj = new test();
echo $token_obj->getAccessCache();
class test{
public function getAccess(){
$access_token = 'This Is A Test Access_Token';//获取access_token
$memcache_obj = memcache_connect("localhost", 11211);
$memcache_obj->add('Access_Token', $access_token, MEMCACHE_COMPRESSED, 50);
//加入数据库存入代码,将新access_token、获取时间(int)time()+7200存入数据库
return $memcache_obj->get('Access_Token');
}
public function getAccessCache(){
$memcache_obj = memcache_connect("localhost", 11211);
$var = $memcache_obj->get('Access_Token');
$access_token=($var)?$var:self::getAccess();
//判断数据是否有效,if无效可以从数据库取access_token,如果access_token 已过期重新获取
$nowtime = (int)time();
$databasetime = self::getDatabasetime('access_token');
if($nowtime >= $databasetime) {
//重新获取access_token
}
return $access_token;
}
}
三、结合缓存和数据库的处理
缓存结合Mysql方案,处理方式是:
判断缓存接口set()和get()的返回值,若失败则转到数据库的操作,将获取的access_token/jsapi_ticket写入数据库,或者从数据库读取。
代码同上