5.3.1 自動緩存與更新Access Token
由於Access Token的有效期只有7200s,而每天調用獲取的次數只有2000次,所以需要將Access Token進行緩存來保證不觸發超過最大調用次數。另外,在微信公眾平台中,絕大多數高級接口都需要Access Token授權才能調用,開發者需要使用中控服務器統一進行緩存與更新,以避免各自刷新而混亂。
下面代碼使用緩存來保存Access Token並在3600s之後自動更新。
1 class class_weixin 2 { 3 var $appid = APPID; 4 var $appsecret = APPSECRET; 5 6 // 構造函數,獲取Access Token 7 public function __construct($appid = NULL, $appsecret = NULL) 8 { 9 if($appid && $appsecret){ 10 $this->appid = $appid; 11 $this->appsecret = $appsecret; 12 } 13 14 // 方法1. 緩存形式 15 if (isset($_SERVER['HTTP_APPNAME'])){ // SAE環境,需要開通memcache 16 $mem = memcache_init; 17 }else { // 本地環境,須安裝memcache 18 $mem = new Memcache; 19 $mem->connect('localhost', 11211) or die ("Could not connect"); 20 } 21 $this->access_token = $mem->get($this->appid); 22 if (!isset($this->access_token) || empty($this->access_token)){ 23 $url = "https:// api.weixin.qq.com/cgi-bin/token?grant_type=client_cre dential&appid=".$this->appid."&secret=".$this->appsecret; 24 $res = $this->http_request($url); 25 $result = json_decode($res, true); 26 $this->access_token = $result["access_token"]; 27 $mem->set($this->appid, $this->access_token, 0, 3600); 28 } 29 30 // 方法2. 本地寫入 31 $res = file_get_contents('access_token.json'); 32 $result = json_decode($res, true); 33 $this->expires_time = $result["expires_time"]; 34 $this->access_token = $result["access_token"]; 35 $callback_ip = $this->get_callback_ip; 36 if (time > ($this->expires_time + 3600) || !isset($callback_ip['ip_list'])){ 37 $url = "https:// api.weixin.qq.com/cgi-bin/token?grant_type=client_cre dential&appid=".$this->appid."&secret=".$this->appsecret; 38 $res = $this->http_request($url); 39 $result = json_decode($res, true); 40 $this->access_token = $result["access_token"]; 41 $this->expires_time = time; 42 file_put_contents('access_token.json', '{"access_token": "'.$this-> access_token.'", "expires_time": '.$this->expires_time.'}'); 43 } 44 } 45 46 protected function http_request($url, $data = null) 47 { 48 $curl = curl_init; 49 curl_setopt($curl, CURLOPT_URL, $url); 50 curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); 51 curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); 52 if (!empty($data)){ 53 curl_setopt($curl, CURLOPT_POST, 1); 54 curl_setopt($curl, CURLOPT_POSTFIELDS, $data); 55 } 56 curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE); 57 $output = curl_exec($curl); 58 curl_close($curl); 59 return $output; 60 } 61 }
上面代碼定義了一個類class_weixin,在類的構造函數中更新並緩存Access Token,該函數介紹使用了兩種方法。
方法一:使用memcache緩存的方法,首先對memcache進行初始化(第15~22行),然後讀取緩存中的Access Token值(第21行)。如果該值不存在或者為空值(第22行),則重新調用接口獲取(第23~26行),並將值存在緩存中,同時設置過期時間為3600s(第27行)。
方法二:使用本地文件讀寫的方式,首先讀取文件access_token.json中的值並對文件中的JSON格式字符串進行編碼轉成數組(第31~34行),再將文件中access_token和expires_time的值保存到this對像中,然後判斷上次保存的時間距離現在是否已超過3600s(第36行)。如果已經超過,則重新調用接口獲取(第37~41行),並將Access Token和時間更新到文件access_token.json中(第42行)。
最後,類中定義了一個protected型函數http_request,該函數使用curl實現向微信公眾平台接口以get或post方式請求數據,幾乎適用於所有微信接口數據的訪問及提交。