Files
liche/market/libraries/Wechatmsg.php
T
2022-09-29 14:32:58 +08:00

290 lines
8.5 KiB
PHP

<?php
include_once 'Hdwechat.php';
/**
* Created by PhpStorm.
* User: xuxb
* Date: 2019/8/8
* Time: 10:36
*/
class Wechatmsg{
private static $max_form = 10;
private $wechat;
private $temp_id = '';//模板消息id
private $temp_appage = '';//模板消息跳转小程序页面
private $temp_appid = '';//模板消息跳转小程序appid
private $temp_url = '';//模板消息跳外链
private $log_file = "wechat_msg.log";
/**
* Wechatmsg constructor.
* @param array $config {'appid':'', 'secret':'', 'token_url':'第三方方式获取token'}
*/
function __construct($config = array()){
$this->wechat = new Hdwechat($config);
$this->cf_app = $config['cf_app'];
if($config){
$this->log_file = "wechat_msg_{$config['appid']}.log";
}
}
function init_wechat($config){
$this->wechat->init($config);
}
/**
* 初始化服务号消息模板
* @param $id (模板ID)
* @param $appage (小程序跳转页)
* @param $appid (小程序appid, 默认当前小程序)
* @param $url (跳转外链)
*/
function init_template($id, $appage = '', $appid = '', $url = ''){
$this->temp_id = $id;
$this->temp_appage = $appage;
$this->temp_appid = $appid;
$this->temp_url = $url;
}
/**
* 发送服务号消息
* @param $openid
* @param $data (消息主体)
* @return mixed
*/
function send_oa($openid, $data){
$access_token = $this->wechat->access_token();
if(!$access_token){
debug_log("[error] ". __FUNCTION__ . ": not access_token; openid={$openid}", $this->log_file);
return false;
}
$pre_url = 'https://api.weixin.qq.com/cgi-bin/message/template/send?access_token=';
$url = $pre_url . $access_token;
$post = array(
'touser' => $openid,
'template_id' => $this->temp_id,
'url' => $this->temp_url ? $this->temp_url : '',
'data' => $data
);
if($this->temp_appage){
$post['miniprogram'] =array(
'appid' => $this->temp_appid,
'pagepath' => $this->temp_appage
);
}
list($code, $res) = $this->curl_json($url, $post);
$ret = json_decode($res, true);
if(40001 == $ret['errcode']){//token过期,重置后请求
$url = $pre_url . $this->wechat->access_token(true);
list($code, $res) = $this->curl_json($url, $post);
$ret = json_decode($res, true);
}
if($ret['errcode'] != 0){
debug_log("[error] ". __FUNCTION__ . ": openid={$openid}", $this->log_file);
return false;
}
return true;
}
/**
* 发送小程序消息
* @param $openid
* @param $data
* @return bool
*/
function send_app($openid, $data){
$access_token = $this->wechat->access_token();
if(!$access_token){
debug_log("[error] ". __FUNCTION__ . ": not access_token; openid={$openid}", $this->log_file);
return false;
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/template/send?access_token=";
$url = $pre_url.$access_token;
$form_id = $this->pop_formid($openid);
if(!$form_id){
debug_log("[error] ". __FUNCTION__ . ": not form_id; openid={$openid}", $this->log_file);
return false;
}
$post = array(
'touser' => $openid,
'template_id' => $this->temp_id,
'form_id' => $form_id,
'page' => $this->temp_appage,
'data' => $data
);
list($code, $res) = $this->curl_json($url, $post);
$ret = json_decode($res, true);
if(40001 == $ret['errcode']){//token过期,重置后请求
$url = $pre_url . $this->wechat->access_token(true);
list($code, $res) = $this->curl_json($url, $post);
$ret = json_decode($res, true);
}
if($ret['errcode'] != 0){
debug_log("[error] ". __FUNCTION__ . ": from_id={$form_id}, openid={$openid}", $this->log_file);
return false;
}
return true;
}
/**
* 发送小程序订阅通知
* @param $openid
* @param $data
* @return bool
*/
function send_appsub($openid, $data){
$access_token = $this->wechat->access_token();
if(!$access_token){
debug_log("[error] ". __FUNCTION__ . ":not access_token; openid={$openid}", $this->log_file);
return false;
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/message/subscribe/send?access_token=";
$url = $pre_url.$access_token;
$post = array(
'touser' => $openid,
'template_id' => $this->temp_id,
'page' => $this->temp_appage,
'data' => $data
);
list($code, $res) = $this->curl_json($url, $post);
$ret = json_decode($res, true);
if(40001 == $ret['errcode']){//token过期,重置后请求
$url = $pre_url . $this->wechat->access_token(true);
list($code, $res) = $this->curl_json($url, $post);
$ret = json_decode($res, true);
}
if($ret['errcode'] != 0){
debug_log("[error] ". __FUNCTION__ . ":openid={$openid}", $this->log_file);
return false;
}
return true;
}
/**
* 收集新的form_id
* @param $openid (用户ID)
* @param $form_id
* @param $expire (到期时间戳)
* @return bool
*/
public function push_formid($openid, $form_id, $expire = 0){
//从redis获取
$r = &load_cache('redis');
$redis = $r->redis();
$key = "wechat_formid_{$this->wechat->appid}_{$openid}";
$long = 7 * 24 * 3600;
!$expire && $expire = time() + $long;
$form = array('id' => $form_id, 'expire' => $expire);
$ret = $redis->lPush($key, json_encode($form));
$len = $redis->lLen($key);
//限制redis列表长度,去掉旧的
$ret && $len > self::$max_form && $redis->rPop($key);
//更新redis有效期
$redis->expire($key, $long);
return false;
}
/**
* 获取formid数量
* @param $openid
* @return mixed
*/
function count_formid($openid){
$key = "wechat_formid_{$this->wechat->appid}_{$openid}";
$r = &load_cache('redis');
$redis = $r->redis();
return $redis->lLen($key);
}
/**
* 查看
* @param $openid
* @return mixed
*/
function view_formid($openid){
$key = "wechat_formid_{$this->wechat->appid}_{$openid}";
$r = &load_cache('redis');
$redis = $r->redis();
return $redis->lRange($key, 0, -1);
}
/**
* 弹出fromid
* @param $openid
* @return string
*/
public function pop_formid($openid){
//从redis获取
$r = &load_cache('redis');
$redis = $r->redis();
$key = "wechat_formid_{$this->wechat->appid}_{$openid}";
$now = time();
while(1) {//循环获取fromid
$form = $redis->rPop($key);
$form && $form = json_decode($form, true);
if(!$form){break;}
if($form['expire'] >= $now){
return $form['id'];
}
}
return '';
}
/**
* @param $url
* @param $data
* @return array
*/
private function curl_json($url, $data){
$data = urldecode(json_encode($data));
debug_log("[info] ". __FUNCTION__ . ":url={$url}, data={$data}", $this->log_file);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//https
if (strlen($url) > 5 && strtolower(substr($url, 0, 5)) == "https") {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
}
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/json; charset=utf-8',
'Content-Length: ' . strlen($data)
)
);
$response = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
debug_log("[info] ". __FUNCTION__ . ":httpcode={$httpCode}, response={$response}", $this->log_file);
return array($httpCode, $response);
}
}