电竞比分网-中国电竞赛事及体育赛事平台

分享

微信調(diào)用接口,防止Access_token過期的方法

 star_xiong 2014-06-23

大家都知道,微信中調(diào)用訂閱用戶接口中需要Access_token,而根據(jù)微信官方文檔中說明:

access_token是公眾號的全局唯一票據(jù),公眾號調(diào)用各接口時都需使用access_token。正常情況下access_token有效期為7200秒,重復(fù)獲取將導(dǎo)致上次獲取的access_token失效


所以這就導(dǎo)致我們每次去獲取訂閱用戶相關(guān)信息的時候都去重新取access_token。這就造成兩個問題。

1. 慢,因為取access_token是遠(yuǎn)程在騰訊提供的API網(wǎng)址上,所以會有一定的延遲。

2. 訪問次數(shù)越多,超出接口調(diào)用限制,會被騰訊限制。我就遭過。后來查API手冊才知道有這句話:

默認(rèn)每個公眾賬號都不能超過下面的頻率限制。 當(dāng)超出調(diào)用接口頻率限制,調(diào)用對應(yīng)接口將會收到如下錯誤信息:

{"errcode":45009,"errmsg":"api freq out of limit"}
接口名稱 頻率限制
獲取憑證接口 200(次/天)
自定義菜單創(chuàng)建接口 100(次/天)
自定義菜單查詢接口 1000(次/天)
自定義菜單刪除接口 100(次/天)

所以針對此問題,我想出了用文本文件或XML來存取動態(tài)的access_token。反正2小時才過期,寫入又不頻繁。當(dāng)然你也可以存取到數(shù)據(jù)庫。

同樣的我用到了SAE的Storage

然后對訪問用戶相關(guān)信息和得到AccessToken的類 進(jìn)行了封裝:
  1. <SPAN style="FONT-SIZE: 14px">        //得到訂閱用戶 (返回數(shù)組)   
  2.     public function GetUserList()  
  3.     {  
  4.         $strjson = $this -> GetUrlReturn("https://api.weixin.qq.com/cgi-bin/user/get?access_token=%s");  
  5.         $openidarr$strjson->data->openid;  
  6.         //print_r($openidarr); 調(diào)試   
  7.         return $openidarr;  
  8.     }  
  9.       
  10.     //得到訂閱用戶詳情(返回對象)   
  11.     public function GetUserDetail($openid)  
  12.     {  
  13.         $url = "https://api.weixin.qq.com/cgi-bin/user/info?access_token=%s&openid={$openid}";  
  14.         $strjson = $this -> GetUrlReturn($url);  
  15.         return $strjson;  
  16.     }  
  17.       
  18.       
  19.     /* 
  20.     * 
  21.     *  私有成員變量 存token值 
  22.     *  因為//access_token是公眾號的全局唯一票據(jù),公眾號調(diào)用各接口時都需使用access_token。 
  23.     *  正常情況下access_token有效期為7200秒,重復(fù)獲取將導(dǎo)致上次獲取的access_token失效。 
  24.     */  
  25.     private $_token ;  
  26.   
  27.     /* 
  28.     * 
  29.     * 私有方法 
  30.     * 
  31.     */  
  32.     //得到Token對象并寫入到配置文件   
  33.     private function InitToken()  
  34.     {  
  35.         $url = sprintf("https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=%s&secret=%s",APPID, SECRET);  
  36.         //echo APPID;   
  37.         $ch = curl_init(); //創(chuàng)建一個新url資源   
  38.         curl_setopt($ch, CURLOPT_URL,$url);  
  39.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
  40.         $a = curl_exec($ch);  
  41.         $strjson=json_decode($a);  
  42.         $token = $strjson->access_token;  
  43.         if (empty($token))  
  44.         {  
  45.             //修改 {"errcode":45009,"errmsg":"api freq out of limit"}   
  46.             echo "錯誤:取得token無效,可能是調(diào)用太頻繁!";    //$strjson   
  47.             throw new Exception('錯誤:取得token無效');   
  48.         }  
  49.           
  50.         $obj = fopen("saestor://weixindata/token.txt","w+");  //SAE禁用fopen本地文件,這里需要Storage  
  51.         fwrite($obj,$token);  
  52.         $this -> _token = $token;  
  53.     }  
  54.       
  55.     //封裝私有方法,調(diào)用得到Get的參數(shù),$needToken默認(rèn)為false, 不取值,這里有一個潛規(guī)則,%s為 self::$_token   
  56.     private function GetUrlReturn($url$needToken = false)  
  57.     {  
  58.         //第一次為空,則從文件中讀取   
  59.         if (empty($this -> _token))  
  60.         {  
  61.             $obj = fopen("saestor://weixindata/token.txt","r");   
  62.             $this -> _token = fgets($obj,1000);  
  63.         }  
  64.           
  65.         //為空則重新取值   
  66.         if (empty($this -> _token) || $needToken)  
  67.         {  
  68.             $this ->InitToken();   
  69.         }  
  70.         $newurl = sprintf($url$this -> _token);  
  71.         $ch = curl_init();  //創(chuàng)建一個新url資源   
  72.         curl_setopt($ch, CURLOPT_URL,$newurl);  
  73.         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);  
  74.         $a = curl_exec($ch);  
  75.         $strjson=json_decode($a);  
  76.         //var_dump($strjson);  //開啟可調(diào)試   
  77.         if (!empty($strjson-> errcode))  
  78.         {  
  79.             switch ($strjson-> errcode){  
  80.                   
  81.                 case 40001:  
  82.                     $this -> GetUrlReturn($url, true); //重新取值,可能是過期導(dǎo)致   
  83.                     break;  
  84.                 case 41001:  
  85.                     throw new Exception("缺少access_token參數(shù):".$strjson->errmsg);   
  86.                     break;  
  87.                 default:  
  88.                     throw new Exception($strjson->errmsg); //其他錯誤,拋出   
  89.                     break;  
  90.                   
  91.             }  
  92.         }  
  93.         return $strjson;  
  94.     }</SPAN>  

大概意思是,默認(rèn)就是從文本文件中取這個值,當(dāng)這個值過期的時候,重新調(diào)用 InitToken 這個方法,獲得最新的AccessToken。這樣AccessToken就永遠(yuǎn)不會過期了。

這是我想到的辦法,歡迎大家給出更好的方法,相互學(xué)習(xí),相互提高。

    本站是提供個人知識管理的網(wǎng)絡(luò)存儲空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊一鍵舉報。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多