search
HomeBackend DevelopmentPHP Tutorial各位大神,你们平时都是怎么保存微信的access_token的?

微信的access_token的获取次数是是限制的,不知道我写的代码是不是正确的

<code>//获取微信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 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;
    }
</code>

回复内容:

微信的access_token的获取次数是是限制的,不知道我写的代码是不是正确的

<code>//获取微信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 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;
    }
</code>

关于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次调用,我怕我一抽筋就用完了,然后就被各种老大吊打,所以,我不会在请求里面获取这个家伙。

因为没涉及到业务我就一整个拷下来。。。应该可以吧

<code>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 applyToken($config);
                continue;
            }

            # 3秒一次的cache检查
            if ( time() - $cacheLastCheckTime get($cacheKey);
            if (!$token) {
                $expTime = $this->applyToken($config);
                $cacheLastCheckTime = time();
            }
        }
    }

    /**
     * 申请token
     * @param $config
     * @return int
     */
    protected function applyToken( $config )
    {
        # 50 秒内不能查询两次,避免抽风一下子将整天的查询都用光了
        if ( time() - $this->lastApplyTime 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' );
    }

}</code>

文档上好像说了吧,这个东西你要保存到你本地的数据库的

你做query的时候,先到本地数据库查找,
没有合适的就query weixin api,使用获得的结果,并且把结果保存到数据库中

下次使用的时候也先query数据库

官方sdk有标准示例。把值存到文件,包括过期时间。每次用的时候比对时间,过期就去取,然后存。反之直接用。

我的方案是写一个JSON文件存储到服务器上,

<code>{
    "access_token" : "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
    "prev_time" : "20140000000"
}</code>

用数据库存过,原理一样,但是觉得这样操作简单一些。

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步骤注意失效时间(最好比官方提早几分钟,以便更新的时候好过度)

每小时更新一次,用的时候直接取这个

Statement
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
php怎么把负数转为正整数php怎么把负数转为正整数Apr 19, 2022 pm 08:59 PM

php把负数转为正整数的方法:1、使用abs()函数将负数转为正数,使用intval()函数对正数取整,转为正整数,语法“intval(abs($number))”;2、利用“~”位运算符将负数取反加一,语法“~$number + 1”。

php怎么实现几秒后执行一个函数php怎么实现几秒后执行一个函数Apr 24, 2022 pm 01:12 PM

实现方法:1、使用“sleep(延迟秒数)”语句,可延迟执行函数若干秒;2、使用“time_nanosleep(延迟秒数,延迟纳秒数)”语句,可延迟执行函数若干秒和纳秒;3、使用“time_sleep_until(time()+7)”语句。

php怎么除以100保留两位小数php怎么除以100保留两位小数Apr 22, 2022 pm 06:23 PM

php除以100保留两位小数的方法:1、利用“/”运算符进行除法运算,语法“数值 / 100”;2、使用“number_format(除法结果, 2)”或“sprintf("%.2f",除法结果)”语句进行四舍五入的处理值,并保留两位小数。

php怎么根据年月日判断是一年的第几天php怎么根据年月日判断是一年的第几天Apr 22, 2022 pm 05:02 PM

判断方法:1、使用“strtotime("年-月-日")”语句将给定的年月日转换为时间戳格式;2、用“date("z",时间戳)+1”语句计算指定时间戳是一年的第几天。date()返回的天数是从0开始计算的,因此真实天数需要在此基础上加1。

php怎么替换nbsp空格符php怎么替换nbsp空格符Apr 24, 2022 pm 02:55 PM

方法:1、用“str_replace("&nbsp;","其他字符",$str)”语句,可将nbsp符替换为其他字符;2、用“preg_replace("/(\s|\&nbsp\;||\xc2\xa0)/","其他字符",$str)”语句。

php怎么判断有没有小数点php怎么判断有没有小数点Apr 20, 2022 pm 08:12 PM

php判断有没有小数点的方法:1、使用“strpos(数字字符串,'.')”语法,如果返回小数点在字符串中第一次出现的位置,则有小数点;2、使用“strrpos(数字字符串,'.')”语句,如果返回小数点在字符串中最后一次出现的位置,则有。

php字符串有没有下标php字符串有没有下标Apr 24, 2022 am 11:49 AM

php字符串有下标。在PHP中,下标不仅可以应用于数组和对象,还可应用于字符串,利用字符串的下标和中括号“[]”可以访问指定索引位置的字符,并对该字符进行读写,语法“字符串名[下标值]”;字符串的下标值(索引值)只能是整数类型,起始值为0。

php怎么读取字符串后几个字符php怎么读取字符串后几个字符Apr 22, 2022 pm 08:31 PM

在php中,可以使用substr()函数来读取字符串后几个字符,只需要将该函数的第二个参数设置为负值,第三个参数省略即可;语法为“substr(字符串,-n)”,表示读取从字符串结尾处向前数第n个字符开始,直到字符串结尾的全部字符。

See all articles

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
2 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Repo: How To Revive Teammates
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌
Hello Kitty Island Adventure: How To Get Giant Seeds
4 weeks agoBy尊渡假赌尊渡假赌尊渡假赌

Hot Tools

WebStorm Mac version

WebStorm Mac version

Useful JavaScript development tools

MinGW - Minimalist GNU for Windows

MinGW - Minimalist GNU for Windows

This project is in the process of being migrated to osdn.net/projects/mingw, you can continue to follow us there. MinGW: A native Windows port of the GNU Compiler Collection (GCC), freely distributable import libraries and header files for building native Windows applications; includes extensions to the MSVC runtime to support C99 functionality. All MinGW software can run on 64-bit Windows platforms.

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

Atom editor mac version download

Atom editor mac version download

The most popular open source editor

SublimeText3 English version

SublimeText3 English version

Recommended: Win version, supports code prompts!