WxTicket.php 3.47 KB
<?php namespace common\exts\wechat;

use common\exts\wechat\Http;
use common\services\redis\RedisConfig;
use yii;
//use Redis;
use common\exts\wechat\Log as WxLog;

/**
 *
 *
 *
 * @package common\exts\wechat
 */
class WxTicket
{
    const API_URL_PREFIX = 'https://api.weixin.qq.com/cgi-bin';
    const GET_TICKET = '/ticket/getticket?';

    /** 获取jsapi 的ticket
     * @param string $appId
     * @param string $appSecret
     * @return null
     */
    public static function getJsApiTicket($appId = '', $appSecret = '')
    {
        if (empty($appId) || empty($appSecret)){
            return null;
        }
        $ticket = self::get($appId, $appSecret);
        return $ticket;
    }

    /** 获取发票 wx_card的类型 ticket
     * @param string $appId
     * @param string $appSecret
     * @return null
     */
    public static function getWxCardTicket($appId = '', $appSecret = '')
    {
        if (empty($appId) || empty($appSecret)){
            return null;
        }
        $ticket = self::get($appId, $appSecret,'wx_card');
        return $ticket;
    }

    /** 获取ticket 的基本信息
     * @param $appId
     * @param $appSecret
     * @param string $type
     * @return null
     */
    public static function get($appId, $appSecret, $type = 'jsapi')
    {

        // 跟踪日志
        WxLog::init();

        $data = null;
        $redis = \yii::$app->redis;
        $cacheTicketKey = RedisConfig::WECHAT_TICKET_PREFIX .'_'. $appId . $type;
        if($redis->exists($cacheTicketKey)){
            $data = json_decode($redis->get($cacheTicketKey));
        }
        if(!$data){
            $data = new \stdClass();
            $data->expire_time = null;
            $data->access_token = null;
        }

        WxLog::DEBUG("get {$type} Ticket: cacheTicketKey[" . $cacheTicketKey . "]: " . json_encode($data));
        if ($data->expire_time < time()) {

            $accessToken = AccessToken::get($appId, $appSecret);//API 的access token

            $url = self::API_URL_PREFIX . self::GET_TICKET."type={$type}&access_token={$accessToken}";
            $getTicketResult = Http::get($url);
            $res = json_decode($getTicketResult);

            WxLog::DEBUG("get {$type} Ticket: result=>" . json_encode($res));
            // 检测到40001access_token失效错误立刻强制刷新,纠正错误[weigong-2016-06-16 16:25:27]
            if(isset($res->errcode) && $res->errcode == 40001) {
                WxLog::WARN("get {$type} Ticket: access_token失效, 自动恢复!");
                $accessToken = AccessToken::get($appId, $appSecret, true); // 强制刷新access_token
                $url = self::API_URL_PREFIX . self::GET_TICKET."type={$type}&access_token={$accessToken}";
                $res = json_decode(Http::get($url));
            }

            $ticket = null;
            if (isset($res->ticket)) {

                $ticket = $res->ticket;

                $data->expire_time = time() + 7000;
                $data->ticket = $ticket;

                $redis->set($cacheTicketKey, json_encode($data));
                $redis->expireat($cacheTicketKey, $data->expire_time); // 到期自动删除

                WxLog::DEBUG("get {$type} Ticket刷新:  ticket=[" .  $data->ticket . "], expire_time=["
                    . $data->expire_time . "], 修改时间=[" . date("Y-m-d H:i:s", time()) . "], cacheTicketKey["
                    . $cacheTicketKey . "]");
            }

        } else {
            $ticket = $data->ticket;
        }

        return $ticket;


    }
}