PHP之 微信access_token验证过期,存入redis,获取

写在前面

关于微信的 access_token,我们经常碰到的问题,就是失效,access_token 一旦失效,跟其相关的操作就无法进行,那么该如何避免呢。采用redis,进行存储处理,可避免在没有失效的情况下,反复请求(防止超过限制)!

一、 验证access_token是否失效,获取 access_token,存入redis并获取

-Redis_access_token_service.php
/**
 * 从redis获取access_token
 *
 * @desc 判断access_token是否失效,未失效,统一从指定服务器151获取access_token;失效,获取,返回,并存入redis
 * @author NangongYi
 * @time 2019/09/28 00:57:58
 *
 */

class Redis_access_token_service
{

    /**
     * 获取access_token
     */
    public function get_t_access_token()
    {
        return $this->check_access_token_is_effective();
    }

    /**
     * 从redis里获取access_token
     * @return string
     */
    private function get_access_token_from_t_redis()
    {
        $this->load->library('tredis');
        return $this->tredis->get('t_redis_access_token');
    }

    /**
     * 将access_token存入到 Tredis
     * @param $access_token
     */
    private function store_access_token_in_t_redis($access_token)
    {
        $this->load->library('tredis');
        $this->tredis->set('t_redis_access_token', $access_token);
    }

    /**
     * 判断存入t_redis的access_token是否有效
     * @desc 无效,获取;有效,返回。
     * @return string $access_token
     */
    private function check_access_token_is_effective()
    {
        $access_token = $this->get_access_token_from_t_redis();
        $url = "https://api.weixin.qq.com/cgi-bin/getcallbackip?access_token=".$access_token;
        $result = $this->https_request($url);
        $data = json_decode($result,true);
        if($data['errcode'] == '40001'){
            $access_token = $this->get_access_token_from_wechat();
            $this->store_access_token_in_t_redis($access_token);
        }
        return $access_token;
    }

    /**
     * https请求
     * @param $url
     * @return mixed
     */
    private function https_request($url)
    {
        $ch = curl_init(); // 创建句柄
        curl_setopt($ch, CURLOPT_URL, $url); // 通过url获取数据
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 跳过证书验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是
        $output = curl_exec($ch);
        curl_close($ch);
        return $output;
    }

    /**
     * 从微信端请求access_token
     * @return mixed
     */
    private function get_access_token_from_wechat()
    {
        // 从配置文件获取配置参数
        $this->load->config('dict/wechat_config');
        $appConfig = $this->config->item('dict_wechat_user');
        // 请求地址
        $url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.
            $appConfig['app_id'].'&secret='.$appConfig['secret'];
        $ch = curl_init(); // 创建句柄
        curl_setopt($ch, CURLOPT_URL, $url); // 通过url获取数据
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);// 跳过证书验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 从证书中检查SSL加密算法是
        $output = json_decode(curl_exec($ch));
        $access_token = $output->access_token;
        curl_close($ch);
        return $access_token;
    }

}

二、Tredis类,定义连接,以及一中的相关操作

-Tredis.php
/**
 * access_token存放的统一Redis
 * @author NangongYi
 * @time 2019/09/29
 */

class Tredis
{
    /**
     * [Class Property Description]
     *
     * @var [data type]
     * @access [public/protected/private]
     */
    private $_redis = NULL;

    /**
     * [Class Property Description]
     *
     * @var [data type]
     * @access [public/protected/private]
     */
    private $_redis_conf = [
        'hostname' => '56.89.116.78',
        'port' => 9870
    ];

    /**
     * [Class Property Description]
     *
     * @var [data type]
     * @access [public/protected/private]
     */
    const NO_RESULT = NULL;

    /**
     * 默认的缓存键
     */
    const CONF_KEY_DEFAULT = 'T_redis';

    /**
     * Constuction
     * @param    array        configuration of redis
     * @desc    boolean        true for sucess or false for faillure
     */
    function __construct($conf_key = NULL)
    {
        $conf_key = ($conf_key == NULL || empty($conf_key['conf_key'])) ?
         self::CONF_KEY_DEFAULT : $conf_key['conf_key'];
        $CI =& get_instance();
        $conf = [];
        if ($CI->config->load('redis', FALSE, TRUE)) {
            if (is_array($CI->config->config[$conf_key])) {
                $conf = $CI->config->config[$conf_key];
            }
        }
        $this->_redis_conf = array_merge($this->_redis_conf, $conf);
        try {
            // redis hostname error
            if (empty($this->_redis_conf['hostname'])) {
                throw new RedisException();
            }
            $this->_redis = new redis();
            $single = $this->_redis->connect($this->_redis_conf['hostname'],
                $this->_redis_conf['port'], $this->_redis_conf['timeout']);
            if (!$single) {
                $this->_redis = NULL;
            }
        } catch (RedisException $e) {
            $this->_redis = NULL;
        }
    }

    /**
     * Storage a value to the redis
     * @access    public
     * @param    string
     * @param    string
     * @param    int  time of living(seconds), if the value is 0s, then the value is permanent.
     * @return    boolean  success return TRUE, failure return FALSE.
     */
    public function set($key, $value, $ttl = 0)
    {
        if ($this->_is_connect() === FALSE) {
            return self::NO_RESULT;
        }
        $ttl = intval($ttl);
        if ($ttl) {
            $result = $this->_redis->setex($key, $ttl, $value);
        } else {
            $result = $this->_redis->set($key, $value);
        }
        return $result;
    }


    /**
     * get value(s)
     *
     * @access    public
     * @param    string
     * @return    mix        return value of the key
     */
    public function get($key)
    {
        if ($this->_is_connect() === FALSE) {
            return self::NO_RESULT;
        }
        return $this->_redis->get($key);
    }

    /**
     * check redis connect or not
     * @return boolean
     */
    private function _is_connect()
    {
        return $this->_redis ? TRUE : FALSE;
    }

    /**
     * 检查redis连接情况
     */
    public function check_connect()
    {
        return $this->_is_connect();
    }

}
就这样,做个整理,方便以后看,如果能帮到,也方便他人吧。
发布了59 篇原创文章 · 获赞 2 · 访问量 5575

猜你喜欢

转载自blog.csdn.net/LDR1109/article/details/102949839