Commonphp
<?php namespace Proxy\Action; use Think\Action; use Vendor\Func\Red; class CommonAction extends Action { public $red; public function _initialize(){ $this->red = Red::create(); header('Content-type: text/html; charset=utf-8'); } /** * 錯誤的json * @param $code * @param string $message * @param array $data */ public function jsonError($code, $message = 'error', $data = []) { $returnData = [ 'code' => $code, 'message' => $message, 'data' => $data ]; header('Content-type:application/json;charset=utf-8'); echo json_encode($returnData); exit; } /** * 正確的json * @param int $code * @param string $message * @param array $data */ public function jsonSuccess($code = 1, $message = 'success', $data = []) { $returnData = [ 'code' => $code, 'message' => $message, 'data' => $data ]; header('Content-type:application/json;charset=utf-8'); echo json_encode($returnData); exit; } /** * 設置Redis * @param $k * @param $v * @param int $expires * @return mixed */ public function setCache($k, $v, $expires = -1) { if ($expires === -1) { return $this->red->set($k, $v); } else { return $this->red->setex($k, $expires, $v); } } /** * 獲取Redis * @param $k * @return mixed */ public function getCache($k) { return $this->red->get($k); } /** * 刪除Redis * @param $k * @return mixed */ public function delCache($k) { return $this->red->delete($k); } /** * 獲取過時時間 * @param $k * @return bool */ public function getCacheTtl($k) { $ttl = $this->red->ttl($k); if ($ttl != '-2') { return $ttl; } else { return false; } } /** * 檢查是否存在 * @param $k * @return mixed */ public function cacheExists($k) { return $this->red->exists($k); } }
AccessTokenhtml
<?php namespace Proxy\Action; use Vendor\Func\Http; /*** * 基礎支持的access_token,每日兩千次 * @package Proxy\Action */ class AccessTokenAction extends CommonAction { const API_TOKEN = 'https://api.weixin.qq.com/cgi-bin/token'; const API_TICKET = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket'; const TOKEN_EXPIRES = 1500; const TICKET_EXPIRES = 1500; protected $access_token_key = ''; // access_token Redis 鍵值名 protected $js_ticket_key = ''; // 憑證 Redis 鍵值名 public function __construct() { parent::__construct(); $this->access_token_key = C('WX_APP_ID').':access_token'; $this->js_ticket_key = C('WX_APP_ID').':js_ticket'; } /** * 獲取全局access_token */ public function get() { // step1 判是存在 $exists = $this->cacheExists($this->access_token_key); // step2 是否強制刷新或者已過時 if ((isset($_GET['flush']) & $_GET['flush']) || !$exists) { $data = $this->reload(); } else { $data = [ 'access_token' => $this->getCache($this->access_token_key), 'expires_in' => $this->getCacheTtl($this->access_token_key) ]; } if (!$data['access_token']) { $this->ajaxReturn($this->jsonError(10002, '接口請求失敗')); } $this->ajaxReturn($this->jsonSuccess(1, '成功', $data)); } /** * 公衆號用於調用微信JS接口的臨時票據 * @return bool */ public function jsTicket() { // step1 判是存在 $exists = $this->cacheExists($this->js_ticket_key); if (!$exists) { // 獲取token $token = $this->getCache($this->access_token_key); setlog($token,[],'token'); // 若是token不存在,從新生成 if (!$token) { // 從新加載一次Token $this->reload(); $token = $this->getCache($this->access_token_key); } $params = [ 'access_token' => $token, 'type' => 'jsapi', ]; $data = Http::newDoGet(self::API_TICKET, $params); $data = json_decode($data, true); if ((int)$data['errcode'] !== 0) { $this->delCache($this->access_token_key); return false; } // 減小1500秒過時時間,提早過時 $this->setCache($this->js_ticket_key, $data['ticket'], $data['expires_in'] - self::TICKET_EXPIRES); } else { $data['ticket'] = $this->getCache($this->js_ticket_key); } return $data['ticket']; } /** * 獲取JS-SDK配置信息 */ public function getConfig() { if (!isset($_GET['uri'])) { $this->ajaxReturn($this->jsonError(0, '參數錯誤')); } $url = $_GET['uri']; $ticket = $this->jsTicket(); setlog($ticket,[],'ticket'); while (!$ticket) { $this->reload(); $ticket = $this->jsTicket(); } $data = [ 'jsapi_ticket' => $ticket, 'nonceStr' => (string)mt_rand(), 'timestamp' => time(), 'url' => $url ]; $sign = $this->getSign($data); $data['signature'] = $sign; $data['appId'] = C('WX_APP_ID'); $this->ajaxReturn($this->jsonSuccess(1, '成功', $data)); } /** * 從新載入 access_token */ protected function reload() { if ($this->cacheExists($this->access_token_key)) { $data = [ 'access_token' => $this->getCache($this->access_token_key), 'expires_in' => $this->getCacheTtl($this->access_token_key) ]; return $data; } $params = [ 'grant_type' => 'client_credential', 'appid' => C('WX_APP_ID'), 'secret' => C('WX_APP_SECRET') ]; $data = Http::newDoGet(self::API_TOKEN, $params); if (!$data) { $this->ajaxReturn($this->jsonError(10002, '接口請求失敗')); } $data = json_decode($data, true); if (isset($data['errcode'])) { $this->ajaxReturn($this->jsonError($data['errcode']), $data['errmsg']); } $this->setCache($this->access_token_key, $data['access_token'], $data['expires_in'] - self::TOKEN_EXPIRES); return $data; } /** * 簽名算法 * @param $data * @return string */ protected function getSign($data) { $str = ''; foreach ($data as $k => $v) { $str .= strtolower($k) .'='.$v; $str .= '&'; } $str = trim($str, '&'); $str = sha1($str); return $str; } }