各位大神,你們平時都是怎麼儲存微信的access_token的?

來源:互聯網
上載者:User
關鍵字 php 微信開發 mysql
的access_token的擷取次數是是限制的,不知道我寫的代碼是不是正確的

//擷取access_token    function get_access_token(){        $appid     = C("APPID");        $appSecret = C("APPSECRET");        $url       = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appSecret";        $where = array(            "appid" =>$appid,            "appsecret" =>$appSecret,        );        $res = M("as")->field('expire,accesssecret,timestamp')->where($where)->select();        if(!$res){//當as表裡沒有資料的時候            dump("!res");            $return  = json_decode(curl($url));            $data['appid'] = $appid;            $data['appsecret'] = $appSecret;            $data['expire'] = $return->expires_in;            $data['accesssecret'] = $return->access_token;            $data['timestamp'] = time();            M("as")->add($data);            $token = $data['accesssecret'];        }else if($res[0]['expire']+$res[0]['timestamp']-30 < time()){//當時間到期的時候            dump("time out");            $return  = json_decode(curl($url));            $data['expire'] = $return->expires_in;            $data['accesssecret'] = $return->access_token;            $data['timestamp'] = time();            M("as")->where("appid='".$appid."'")->save($data);            $token = $data['accesssecret'];        }else{            $token = $res[0]['accesssecret'];        }        return $token;    }

回複內容:

的access_token的擷取次數是是限制的,不知道我寫的代碼是不是正確的

//擷取access_token    function get_access_token(){        $appid     = C("APPID");        $appSecret = C("APPSECRET");        $url       = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=$appid&secret=$appSecret";        $where = array(            "appid" =>$appid,            "appsecret" =>$appSecret,        );        $res = M("as")->field('expire,accesssecret,timestamp')->where($where)->select();        if(!$res){//當as表裡沒有資料的時候            dump("!res");            $return  = json_decode(curl($url));            $data['appid'] = $appid;            $data['appsecret'] = $appSecret;            $data['expire'] = $return->expires_in;            $data['accesssecret'] = $return->access_token;            $data['timestamp'] = time();            M("as")->add($data);            $token = $data['accesssecret'];        }else if($res[0]['expire']+$res[0]['timestamp']-30 < time()){//當時間到期的時候            dump("time out");            $return  = json_decode(curl($url));            $data['expire'] = $return->expires_in;            $data['accesssecret'] = $return->access_token;            $data['timestamp'] = time();            M("as")->where("appid='".$appid."'")->save($data);            $token = $data['accesssecret'];        }else{            $token = $res[0]['accesssecret'];        }        return $token;    }

關於AccessToken

1.每天請求次數為2000次;
2.每個Access_Token有效期間為2小時;

儲存方案:

1.資料庫:通過介面擷取到 Access_Token 之後,將 Access_Token + 目前時間戳序列化儲存,每次需要 Access_Token 時,從資料庫取出,然後還原序列化對比時間戳記,如果到期,重新調用介面並更新資料庫記錄;

2.NoSQl:這裡以 Redis 為例子。通過介面擷取到 Access_Token 之後,存入 Redis 並設定到期時間,每次需要 Access_Token 時,去 Redis 查詢,如果沒有查詢到記錄說明上次擷取到的 Access_Token 已到期,重新擷取並更新記錄;

3.檔案儲存體:這個比較適合單一公眾號的情況。通過介面擷取到 Access_Token 之後,存入檔案,可以選擇性將時間戳記一併存入。每次需要 Access_Token 時,如果之前未記錄時間戳記,則比較檔案修改時間與目前時間,然後選擇讀取記錄或者重新調用介面更新記錄,否則先讀取檔案內容,然後對比之後選擇下一步行為。

NoSQL方案 > 資料庫 > 檔案管理

使用session加到期時間

那個,特麼才2000次調用,我怕我一抽筋就用完了,然後就被各種老大吊打,所以,我不會在請求裡面擷取這個傢伙。

因為沒涉及到業務我就一整個拷下來。。。應該可以吧

namespace Kinhom\Cli\Tasks;use Kinhom\Cli\Tasks\Impl\TaskInterface;use Phalcon\Cli\Task;use Phalcon\Di;/** * 用於更新access_token * * Class WeiXinAccessTokenTask * @package Kinhom\Cli\Tasks */class WeiXinAccessTokenTask extends Task implements TaskInterface{    # 最後申請時間    protected $lastApplyTime = 0;    # 間隔時間 : 50秒內的申請算連擊,根據每天只能調用2000次估算出來    protected $intervalTime = 50;    /**     * 更新的accessToken     */    public function runAction()    {        # token有效時間        $expTime = 0;        # 提前20分鐘擷取token        $pre = 20 * 60;        $config = $this->getDI()->get('config')['weixin']->toArray();        $cache = $this->getCache();        $cacheKey = $config['cacheKey'];        # 最後檢查cache時間,每隔一定時間會檢查cache是否存在        $cacheLastCheckTime = time();        while (true) {            # 如果時間到了就更新token            if ( $expTime <= time() - $pre ) {                $expTime = $this->applyToken($config);                continue;            }            # 3秒一次的cache檢查            if ( time() - $cacheLastCheckTime < 3 ) {                continue;            }            # 如果cache裡沒有就更新token            $token = $cache->get($cacheKey);            if (!$token) {                $expTime = $this->applyToken($config);                $cacheLastCheckTime = time();            }        }    }    /**     * 申請token     * @param $config     * @return int     */    protected function applyToken( $config )    {        # 50 秒內不能查詢兩次,避免抽風一下子將整天的查詢都用光了        if ( time() - $this->lastApplyTime < $this->intervalTime ) {            return time();        }        $appId = $config['appId'];        $secret = $config['appSecret'];        $url = "https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid={$appId}&secret={$secret}";        $curl = curl_init($url);        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);        curl_setopt($curl,CURLOPT_HEADER, 0);        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);        $data = curl_exec($curl);        curl_close($curl);        if ( ! $data ) {            $this->getLogger()->error( '擷取公眾號token失敗,返回為空白' );            return time();        }        $result = json_decode($data, true);        if ( ! $result ) {            $this->getLogger()->error( '擷取公眾號token失敗,返回異常:'.$data );            return time();        }        $cache = $this->getCache();        $cacheKey = $config['cacheKey'];        $cache->save($cacheKey,$result['access_token'],$result['expires_in']);        return time() + $result['expires_in'];    }    /**     * 擷取緩衝     * @return \Phalcon\Cache\BackendInterface     */    protected function getCache()    {        return $this->getDI()->get('cache');    }    /**     * 擷取日誌     * @return \Phalcon\Logger\AdapterInterface     */    protected function getLogger()    {        return $this->getDI()->get( 'logger' );    }}

文檔上好像說了吧,這個東西你要儲存到你本地的資料庫的

你做query的時候,先到本機資料庫尋找,
沒有合適的就query weixin api,使用獲得的結果,並且把結果儲存到資料庫中

下次使用的時候也先query資料庫

官方sdk有標準樣本。把值存到檔案,包括到期時間。每次用的時候比對時間,到期就去取,然後存。反之直接用。

我的方案是寫一個JSON檔案儲存體到伺服器上,

{    "access_token" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",    "prev_time" : "20140000000"}

用資料庫存過,原理一樣,但是覺得這樣操作簡單一些。

http://mp.weixin.qq.com/wiki/14/9f9c82c1af308e3b14ba9b973f99a8ba.html
官方文檔說了,推薦使用代理服務器專門負責access_token的事情,在代理服務器裡面做緩衝和到期重新擷取,所有需要擷取access_token都程式都到代理服務器去請求,這樣你就不用擔心超過2000次的問題,也更不用擔心多個程式請求access_token,後者重新整理了access_token,前者會不會失效的問題。

我的習慣是三層去擷取token

  1. 首先讀取緩衝(如memcache、redis或檔案快取都行)

  2. 如果緩衝讀取失敗,就讀取資料庫(並寫入緩衝。下次就直接讀取緩衝了)

  3. 最後通過API介面擷取,擷取後寫入到資料庫,並寫入到緩衝

其中1,2步驟注意失效時間(最好比官方提早幾分鐘,以便更新的時候好過度)

每小時更新一次,用的時候直接取這個

  • 相關文章

    聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.