Files
liche/api/libraries/Hdwechat.php
T
2021-07-29 14:49:01 +08:00

696 lines
24 KiB
PHP
Executable File

<?php
/**
* Created by PhpStorm.
* User: xuxb
* Date: 2019/7/25
* Time: 16:40
*/
class Hdwechat
{
private $log_file = "wechat.log";
private $log_dir;
public $appid = '';
public $secret = '';
public $token_url = '';//第三方地址获取token
private $access_token = '';
private $hd_wechat;
/**
* Hdwechat constructor.
* @param array $config {'appid':'', 'secret':'', 'token_url':'第三方方式获取token'}
*/
function __construct($config = array())
{
$config && $this->init($config);
$class_name = get_class($this);
$this->log_file = "{$class_name}_{$this->appid}.log";
$this->log_dir = "{$class_name}_{$this->appid}";
}
/**
* @param $config ('appid', 'secret')
*/
function init($config)
{
$this->appid = $config['appid'];
$this->secret = $config['secret'];
$this->token_url = $config['token_url'];
$CI = &get_instance();
$CI->load->library("hd_wechat", $config);
/*这里用new的方式,因为load如果对象已经存在,会去取旧的,不会生成新配置的对象*/
$this->hd_wechat = new Hd_wechat($config);
}
/**
* 获取或者重置access_token
* @param $reset (是否重置)
* @return mixed
*/
function access_token($reset = false)
{
$this->access_token = $this->hd_wechat->access_token($reset);
return $this->access_token;
}
function activityid($unionid)
{
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/message/wxopen/activityid/create?unionid={$unionid}&access_token=";
$url = $pre_url . $access_token;
$res = $this->url_get($url);
$ret = json_decode($res, true);
return $ret;
}
/**
* 生成二维码
* @param $filename (文件名称)
* @param $scene (最大32个可见字符,只支持数字,大小写英文以及部分特殊字符:!#$&'()*+,/:;=?@-._~,其它字符请自行编码为合法字符(因不支持%,中文无法使用 urlencode 处理,请使用其他编码方式)
* @param $page (必须是已经发布的小程序存在的页面(否则报错),例如 pages/index/index, 根路径前不要填加 /,不能携带参数(参数请放在scene字段里),如果不填写这个字段,默认跳主页面)
* @param $width (二维码的宽度,单位 px,最小 280px,最大 1280px,默认430px)
* @return array {'file':'文件路径', 'url':'访问相对路径'}
*/
function qrcode($filename, $scene, $page, $width)
{
$file = APPPATH . '../www/api/wx/' . $filename . '.png';
$dir = substr($file, 0, strrpos($file, '/'));
if (!is_dir($dir)) {
$ret = mkdir($dir, 0777, true);// 如果文件夹不存在,将以递归方式创建该文件夹
if (!$ret) {
debug_log("[error] " . __FUNCTION__ . ": mkdir {$ret}, filename:{$filename}, scene:{$scene}, page:{$page}, width:{$width}", $this->log_file);
return array();
}
}
if (file_exists($file)) {
return array('file' => $file, 'url' => 'wx/' . $filename . '.png');
}
$access_token = $this->access_token();
var_dump($access_token);exit;
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = 'https://api.weixin.qq.com/wxa/getwxacodeunlimit?access_token=';
$url = $pre_url . $access_token;
$data = array(
'scene' => $scene,
'page' => $page,
'width' => $width ? $width : 430,
);
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && 40001 == $ret['errcode']) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
}
if (isset($ret['errcode'])) {
debug_log("[error] " . __FUNCTION__ . ": httpcode:{$code}, response:{$res}, filename:{$filename}, scene:{$scene}, page:{$page}, width:{$width}", $this->log_file);
return array();
}
$ret = file_put_contents($file, $res);
if (false === $ret) {
debug_log("[error] " . __FUNCTION__ . ": file_put_contents {$ret}, filename:{$filename}, scene:{$scene}, page:{$page}, width:{$width}", $this->log_file);
return array();
}
return array('file' => $file, 'url' => 'wx/' . $filename . '.png');
}
/**
* 获取微信用户信息
* @param $openid
* @return array|mixed
*/
function user($openid)
{
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/user/info?openid={$openid}&lang=zh_CN&access_token=";
$url = $pre_url . $access_token;
$res = $this->url_get($url);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && 40001 == $ret['errcode']) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
$res = $this->url_get($url);
$ret = json_decode($res, true);
}
if (isset($ret['errcode'])) {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
/*
{
"subscribe": 1,//是否关注
"openid": "o6_bmjrPTlm6_2sgVt7hMZOPfL2M",
"nickname": "Band",
"sex": 1,
"language": "zh_CN",
"city": "广州",
"province": "广东",
"country": "中国",
"headimgurl":"http://thirdwx.qlogo.cn/mmopen/g3MonUZtNHkdmzicIlibx6iaFqAc56vxLSUfpb6n5WKSYVY0ChQKkiaJSgQ1dZuTOgvLLrhJbERQQ4eMsv84eavHiaiceqxibJxCfHe/0",
"subscribe_time": 1382694957,
"unionid": " o6_bmasdasdsad6_2sgVt7hMZOPfL"
"remark": "",
"groupid": 0,
"tagid_list":[128,2],
"subscribe_scene": "ADD_SCENE_QR_CODE",
"qr_scene": 98765,
"qr_scene_str": ""
}
*/
return $ret;
}
/**
* 批获取用户信息
* @param $openids
* @return array|mixed
*/
function users($openids)
{
$lists = array();
foreach ($openids as $openid) {
$lists[] = array(
"openid" => $openid,
'lang' => "zh_CN",
);
}
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/user/info/batchget?access_token=";
$url = $pre_url . $access_token;
$data = array('user_list' => $lists);
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && 40001 == $ret['errcode']) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
}
if (isset($ret['errcode'])) {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
/*
{
"user_info_list": [
{
"subscribe": 1,
"openid": "otvxTs4dckWG7imySrJd6jSi0CWE",
"nickname": "iWithery",
"sex": 1,
"language": "zh_CN",
"city": "揭阳",
"province": "广东",
"country": "中国",
"headimgurl": "http://thirdwx.qlogo.cn/mmopen/xbIQx1GRqdvyqkMMhEaGOX802l1CyqMJNgUzKP8MeAeHFicRDSnZH7FY4XB7p8XHXIf6uJA2SCunTPicGKezDC4saKISzRj3nz/0",
"subscribe_time": 1434093047,
"unionid": "oR5GjjgEhCMJFyzaVZdrxZ2zRRF4",
"remark": "",
"groupid": 0,
"tagid_list":[128,2],
"subscribe_scene": "ADD_SCENE_QR_CODE",
"qr_scene": 98765,
"qr_scene_str": ""
},
{
"subscribe": 0,
"openid": "otvxTs_JZ6SEiP0imdhpi50fuSZg"
}
]
}
* */
return $ret;
}
/**
* 获取用户列表
* @param $next_openid (起始openid,默认从头开始)
* @return array {'total':'总数', 'count':'这次获取数', 'data':{'openid'['openid'],'next_openid':'下一页起始openid'}}
*/
function openids($next_openid = '')
{
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/user/get?next_openid={$next_openid}&access_token=";
$url = $pre_url . $access_token;
$res = $this->url_get($url);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && 40001 == $ret['errcode']) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
$res = $this->url_get($url);
$ret = json_decode($res, true);
}
if (isset($ret['errcode'])) {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
/*
{
"total":2,
"count":2,
"data":{
"openid":["OPENID1","OPENID2"]},
"next_openid":"NEXT_OPENID"
}
*/
return $ret;
}
/**
* 获取回放源视频和获取直播房间列表 共用(调用限额 10 万次/天,200 次/分钟)
* @param $start 起始拉取房间,start = 0 表示从第 1 个房间开始拉取
* @param $limit 每次拉取的个数上限,不要设置过大,建议 100 以内
* @param $room_id 直播间id,当传直播间id获取视频
*/
function getliveinfo($start = 0, $limit = 20, $room_id = '')
{
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$data = array(
'start' => $start,
'limit' => $limit
);
if ($room_id) {//直播间id
$data['room_id'] = $room_id;
$data['action'] = 'get_replay';
}
$pre_url = "https://api.weixin.qq.com/wxa/business/getliveinfo?access_token=";
$url = $pre_url . $access_token;
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && $ret['errcode'] != 'ok') {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
return $ret;
}
/**
* @return array|mixed
*/
function tag_get()
{
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/tags/get?access_token=";
$url = $pre_url . $access_token;
$res = $this->url_get($url);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && (40001 == $ret['errcode'] || -1 == $ret['errcode'])) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
$res = $this->url_get($url);
$ret = json_decode($res, true);
}
if (isset($ret['errcode'])) {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
/*
{
"tags":[{
"id":1,
"name":"每天一罐可乐星人",
"count":0 //此标签下粉丝数
}]
}
*/
return $ret;
}
/**
* @param $tagid
* @param string $next_openid
* @return array|mixed
*/
function tag_user($tagid, $next_openid = '')
{
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$pre_url = "https://api.weixin.qq.com/cgi-bin/user/tag/get?access_token=";
$url = $pre_url . $access_token;
$data = array(
'tagid' => $tagid,
'next_openid' => $next_openid,
);
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && (40001 == $ret['errcode'] || -1 == $ret['errcode'])) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
list($code, $res) = $this->curl_post($url, $data);
$ret = json_decode($res, true);
}
if (isset($ret['errcode'])) {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
/*
{
"count":2,//这次获取的粉丝数量
"data":{//粉丝列表
"openid":[
"ocYxcuAEy30bX0NXmGn4ypqx3tI0",
"ocYxcuBt0mRugKZ7tGAHPnUaOW7Y" ]
},
"next_openid":"ocYxcuBt0mRugKZ7tGAHPnUaOW7Y"//拉取列表最后一个用户的openid
}
*/
return $ret;
}
/**
* 内容安全校验
* @param $type "msg内容, img图片"
* @param $data
* @return array|mixed
*/
function sec_check($type, $data)
{
$pre_url = "https://api.weixin.qq.com/wxa/servicemarket?access_token=";
$post_data = array();
switch ($type) {
case 'msg':
$post_data = array(
"service" => "wxee446d7507c68b11",
'api' => "msgSecCheck",
"client_msg_id" => "client_msg_id_1",
"data" => array(
"Action" => "TextApproval",
"Text" => $data,
)
);
break;
case 'img':
$post_data = array(
"service" => "wxee446d7507c68b11",
'api' => "msgSecCheck",
"client_msg_id" => "client_msg_id_1",
"data" => array(
"Action" => "ImageModeration",
"Scenes" => ["PORN", "POLITICS", "TERRORISM"],
"ImageUrl" => $data,
"ImageBase64" => "",
"Config" => "",
"Extra" => ""
)
);
break;
}
if (!$post_data) {
debug_log("[error]# " . __FUNCTION__ . ": unknow type:{$type}", $this->log_file);
return array();
}
$access_token = $this->access_token();
if (!$access_token) {
debug_log("[error] " . __FUNCTION__ . ": not access_token", $this->log_file);
return array();
}
$url = $pre_url . $access_token;
list($code, $res) = $this->curl_post($url, $post_data);
$ret = json_decode($res, true);
if (isset($ret['errcode']) && 40001 == $ret['errcode']) {//token过期,重置后请求
$url = $pre_url . $this->access_token(true);
list($code, $res) = $this->curl_post($url, $post_data);
$ret = json_decode($res, true);
}
if (0 != $ret['errcode'] && 80714) {
debug_log("[error] " . __FUNCTION__ . ":url=$url, res={$res}", $this->log_file);
return array();
}
switch ($type) {
case "msg":
/*
{
"errcode": 0,
"errmsg": "ok",
"data": "{$data}",
"request_id": "MLw1pg8TN_O8SFol2BwbHNsKJtGl_Vf7WEaBObyDjYifxq9hx8v-TpQne9X_1jilYwA",
"provider_errmsg": "",
}
$data={
"Response": {
"EvilTokens": [
{
"EvilFlag": 1,
"EvilType": 2,
"EvilKeywords": [
"骚逼"
]
},
{
"EvilFlag": 1,
"EvilType": 3,
"EvilKeywords": [
"你妈逼",
"我草",
"王八蛋",
"你他妈的"
]
},
{
"EvilFlag": 2,
"EvilType": 3,
"EvilKeywords": [
"他妈的",
"你他妈",
"骚逼",
"我草你妈",
"王八"
]
}
],
"RequestId": "2cb93e69-8f5a-47a3-8dc3-93f177f2912b"
}
}
*/
$EvilFlags = array("正常", "恶意", "可疑送审");
$EvilTypes = array(
0 => '正常',
1 => '政治',
2 => '色情',
3 => '辱骂/低俗',
4 => '暴恐/毒品',
5 => '广告/灌水',
6 => '迷信/邪教',
7 => '其他违法(如跨站追杀/恶意竞争等)',
8 => '综合',
9 => '联系方式/链接',
);
$msg = "";
if (0 == $ret['errcode'] && $ret['data']) {
$response = json_decode($ret['data'], true);
if ($response['Response'] && $response['Response']['EvilTokens']) {
$rows = $response['Response']['EvilTokens'];
foreach ($rows as $v) {
$msg .= "{$EvilFlags[$v['EvilFlag']]}-{$EvilTypes[$v['EvilType']]}:" . implode(',', $v['EvilKeywords']) . ";";
}
}
$ret['msg'] = $msg;
}
break;
case "img":
/* 图片审核返回值
{
"errcode": 0,
"errmsg": "ok",
"data": "{$data}",
"request_id": "MLxQcr8W8oGH0nrM7d0FNjYtWap5v-FIjCVDH0zVV9oprnDyD2sKCiBPl7iT8zWEWPw",
"provider_errmsg": "",
}
$data={
"Response": {
"PornResult": {
"Suggestion": "BLOCK",
"Confidence": 99,
"AdvancedInfo": "",
"Type": "PORN",
"Code": 0,
"Msg": "OK"
},
"PoliticsResult": {
"Suggestion": "PASS",
"Confidence": 37,
"AdvancedInfo": "",
"Type": "DNA",
"Code": 0,
"Msg": "OK",
"FaceResults": []
},
"TerrorismResult": {
"Suggestion": "PASS",
"Confidence": 0,
"AdvancedInfo": "",
"Type": "LABEL",
"Code": 0,
"Msg": "OK",
"FaceResults": []
},
"DisgustResult": null,
"TextResult": null,
"Suggestion": "BLOCK",
"Extra": "",
"RequestId": "33b73a27-8bb6-48d6-855e-cb6bab2faf20"
}
}
*/
$sugs = array("pass" => "正常", 'review' => "疑似", "block" => "违规");
$types = array(
"PornResult" => "色情",
"TerrorismResult" => "暴恐",
"PoliticsResult" => "政治敏感",
"DisgustResult" => "恶心内容",
"TextResult" => "文字",
);
$msg = "";
if (0 == $ret['errcode'] && $ret['data']) {
$response = json_decode($ret['data'], true);
if ($response['Response']) {
foreach ($response['Response'] as $k => $type) {
if (!$types[$k] || !$type) {
continue;
}
$sug = strtolower($type['Suggestion']);
if ('pass' == $sug) {
continue;
}
$msg .= "{$types[$k]}:{$sugs[$sug]};";
}
}
$ret['msg'] = $msg;
}
break;
}
return $ret;
}
/**
* 从其他接口获取token,保证获取token不影响其他平台
* @param $url
* @return string
*/
private function get_self_token($url)
{
$res = trim(file_get_contents($url));
debug_log("[info] " . __FUNCTION__ . ":url={$url}, res={$res}", $this->log_file);
return $res;
}
/**
* @param $url
* @param $data
* @return array
*/
private function curl_post($url, $data)
{
debug_log("[info] " . __FUNCTION__ . ":url={$url}, data=" . json_encode($data, JSON_UNESCAPED_UNICODE), $this->log_file);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data, JSON_UNESCAPED_UNICODE));
$res = curl_exec($ch);
$code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
$size = strlen($res);
if ($size > 5000) {
debug_log("[info] " . __FUNCTION__ . ":httpcode={$code}, response is big only show size={$size}", $this->log_file);
} else {
debug_log("[info] " . __FUNCTION__ . ":httpcode={$code}, response={$res}", $this->log_file);
}
return array($code, $res);
}
/**
* @param $url
* @return string
*/
private function url_get($url)
{
$res = file_get_contents($url);
debug_log("[info] " . __FUNCTION__ . ":url={$url}, res={$res}", $this->log_file);
return $res;
}
}