Files
2025-11-28 10:08:12 +08:00

149 lines
5.3 KiB
PHP

<?php
namespace lib\wechat;
use Exception;
class WechatAPI
{
private $wid;
private $accessToken;
private $jsapiTicket;
public function __construct($id)
{
$this->wid = $id;
}
public function getAccessToken($force = false)
{
global $DB;
if(!empty($this->accessToken)) return $this->accessToken;
$DB->beginTransaction();
try{
$row = $DB->getRow("SELECT * FROM pre_weixin WHERE id='{$this->wid}' LIMIT 1 FOR UPDATE");
if(!$row) throw new Exception('记录不存在');
if($row['access_token'] && strtotime($row['expiretime']) - 200 >= time() && !$force){
$DB->rollback();
$this->accessToken = $row['access_token'];
return $this->accessToken;
}
$appid = $row['appid'];
$secret = $row['appsecret'];
$url = "https://api.weixin.qq.com/cgi-bin/stable_token";
$post = json_encode(['grant_type'=>'client_credential', 'appid'=>$appid, 'secret'=>$secret]);
$output = get_curl($url, $post);
$res = json_decode($output, true);
if (isset($res['access_token'])) {
$this->accessToken = $res['access_token'];
$expire_time = time() + $res['expires_in'];
$DB->exec("UPDATE pre_weixin SET access_token=:access_token,updatetime=NOW(),expiretime=:expiretime WHERE id=:id", [':access_token'=>$this->accessToken, ':expiretime'=>date("Y-m-d H:i:s", $expire_time), ':id'=>$this->wid]);
}elseif(isset($res['errmsg'])){
throw new Exception('AccessToken获取失败:'.$res['errmsg']);
}else{
throw new Exception('AccessToken获取失败');
}
$DB->commit();
return $this->accessToken;
}catch(Exception $e){
$DB->rollback();
throw $e;
}
}
public function generate_scheme($path, $query, $expire = 600)
{
$access_token = $this->getAccessToken();
$url = "https://api.weixin.qq.com/wxa/generatescheme?access_token=".$access_token;
$data = ['jump_wxa'=>['path'=>$path, 'query'=>$query]];
if($expire>0){
$data['is_expire'] = true;
$data['expire_time'] = time()+$expire;
}
$output = get_curl($url, json_encode($data));
$res = json_decode($output, true);
if ($res && $res['errcode'] == 0) {
return $res['openlink'];
}else{
throw new Exception('urlscheme生成失败:'.$res['errmsg']);
}
}
//发送微信公众号模板消息
public function sendTemplateMessage($openid, $template_id, $jumpurl, $data){
$access_token = $this->getAccessToken();
$url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token='.$access_token;
$post = [
'touser' => $openid,
'template_id' => $template_id,
'url' => $jumpurl,
'data' => $data
];
$response = get_curl($url, json_encode($post));
$res = json_decode($response, true);
if ($res && $res['errcode'] == 0) {
return true;
}else{
throw new Exception('模板消息发送失败:'.$res['errmsg']);
}
}
public function getJsapiTicket($force = false)
{
global $CACHE;
if(!empty($this->jsapiTicket)) return $this->jsapiTicket;
$cachekey = 'wx_jsapi_ticket_'.$this->wid;
$row = $CACHE->read($cachekey);
if($row){
$row = unserialize($row);
if($row['ticket'] && strtotime($row['expiretime']) - 200 >= time() && !$force){
$this->jsapiTicket = $row['ticket'];
return $this->jsapiTicket;
}
}
$access_token = $this->getAccessToken();
$url = 'https://api.weixin.qq.com/cgi-bin/ticket/getticket?access_token='.$access_token.'&type=jsapi';
$output = get_curl($url);
$res = json_decode($output, true);
if (isset($res['ticket'])) {
$this->jsapiTicket = $res['ticket'];
$expire_time = time() + $res['expires_in'];
$CACHE->save($cachekey, ['ticket'=>$this->jsapiTicket, 'expiretime'=>date("Y-m-d H:i:s", $expire_time)], $res['expires_in']);
}elseif(isset($res['errmsg'])){
throw new Exception('JsapiTicket获取失败:'.$res['errmsg']);
}else{
throw new Exception('JsapiTicket获取失败');
}
}
public function getJsapiConfig($appid, $url, $jsApiList, $debug = false)
{
$ticket = $this->getJsapiTicket();
$data = [
'jsapi_ticket' => $ticket,
'timestamp' => time(),
'noncestr' => random(16),
'url' => $url
];
$config = [
'debug' => $debug,
'appId' => $appid,
'timestamp' => $data['timestamp'],
'nonceStr' => $data['noncestr'],
'signature' => $this->getSignature($data),
'jsApiList' => $jsApiList
];
return $config;
}
public function getSignature($data)
{
ksort($data);
$params = array();
foreach ($data as $key => $value) {
$params[] = "{$key}={$value}";
}
return sha1(join('&', $params));
}
}