Files
BESCMS/dayrui/App/Weixin/Config/Init.php
T

461 lines
16 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
$this->weixin = $this->get_cache('weixin'.(WEIXIN_MORE_ID > 1 ? '_more_'.WEIXIN_MORE_ID : '')); // 配置
// 获取微信表名
function weixin_wxtable($name, $wxid = WEIXIN_MORE_ID) {
$prefix = $wxid > 1 ? 'more_'.$wxid.'_' : '';
if ($name != 'weixin') {
$name = 'weixin_'.$name;
}
return $prefix.$name;
}
// 获取access_token
function weixin_get_access_token($data = []) {
if (is_array($data) && $data) {
$config = $data;
} elseif ($data == 'update') {
// 重写写入
$config = \Phpcmf\Service::C()->weixin['account'];
} else {
$cache_data = \Phpcmf\Service::L('cache')->get_auth_data('weixin_access_token_'.WEIXIN_MORE_ID, 1, 2200);
if (is_array($cache_data)) {
if ($cache_data['endtime'] && $cache_data['endtime'] > SYS_TIME && $cache_data['access_token']) {
return dr_return_data(1, $cache_data['access_token']);
} elseif (!\Phpcmf\Service::C()->weixin['account']) {
return dr_return_data(0, '未配置微信接入参数');
}
}
$config = \Phpcmf\Service::C()->weixin['account'];
}
if (!$config['appid'] || !$config['appsecret']) {
return dr_return_data(0, 'appid或者appsecret没填写');
}
$result = wx_get_https_json_data('https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid='.$config['appid'].'&secret='.$config['appsecret']);
if (!$result['code']) {
return dr_return_data(0, 'AccessToken'.$result['msg']);
} elseif (!$result['data']['access_token']) {
return dr_return_data(0, 'AccessToken为空,请重试');
}
$result['data']['endtime'] = SYS_TIME + 2360;
$rt = \Phpcmf\Service::L('cache')->set_auth_data('weixin_access_token_'.WEIXIN_MORE_ID, $result['data'], 1);
if (!$rt) {
return dr_return_data(0, 'AccessToken/cache/authcode/目录不可写,文件写入失败');
}
return dr_return_data(1, $result['data']['access_token']);
}
// 小程序获取access_token
function xcx_get_access_token($data = []) {
if (is_array($data) && $data) {
$config = $data;
} elseif ($data == 'update') {
// 重写写入
$config = \Phpcmf\Service::C()->weixin['xcx'];
} else {
$cache_data = \Phpcmf\Service::L('cache')->get_auth_data('xcx_access_token_'.WEIXIN_MORE_ID, 1, 2200);
if (is_array($cache_data)) {
if ($cache_data['endtime'] && $cache_data['endtime'] > SYS_TIME && $cache_data['access_token']) {
return dr_return_data(1, $cache_data['access_token']);
} elseif (!\Phpcmf\Service::C()->weixin['xcx']) {
return dr_return_data(0, '未配置小程序接入参数');
}
}
$config = \Phpcmf\Service::C()->weixin['xcx'];
}
if (!$config['appid'] || !$config['appsecret']) {
return dr_return_data(0, 'appid或者appsecret没填写');
}
$url = 'https://api.weixin.qq.com/cgi-bin/token?grant_type=client_credential&appid=' . $config['appid'] . '&secret=' . $config['appsecret'] . '';
$result = wx_get_https_json_data($url);
if (!$result['code']) {
return dr_return_data(0, 'AccessToken'.$result['msg']);
} elseif (!$result['data']['access_token']) {
return dr_return_data(0, 'AccessToken为空,请重试');
}
$result['data']['endtime'] = SYS_TIME + 2360;
$rt = \Phpcmf\Service::L('cache')->set_auth_data('xcx_access_token_'.WEIXIN_MORE_ID, $result['data'], 1);
if (!$rt) {
return dr_return_data(0, 'AccessToken/cache/authcode/目录不可写,文件写入失败');
}
return dr_return_data(1, $result['data']['access_token']);
}
function ihttp_request($url, $post = '', $extra = array(), $timeout = 60) {
$urlset = parse_url($url);
if (empty($urlset['path'])) {
$urlset['path'] = '/';
}
if (!empty($urlset['query'])) {
$urlset['query'] = "?{$urlset['query']}";
}
if (empty($urlset['port'])) {
$urlset['port'] = $urlset['scheme'] == 'https' ? '443' : '80';
}
if (strexists($url, 'https://') && !extension_loaded('openssl')) {
if (!extension_loaded("openssl")) {
return dr_return_data(0, ' 请开启您PHP环境的openssl');
}
}
if (function_exists('curl_init') && function_exists('curl_exec')) {
$ch = curl_init();
if (!empty($extra['ip'])) {
$extra['Host'] = $urlset['host'];
$urlset['host'] = $extra['ip'];
unset($extra['ip']);
}
curl_setopt($ch, CURLOPT_URL, $urlset['scheme'] . '://' . $urlset['host'] . ($urlset['port'] == '80' ? '' : ':' . $urlset['port']) . $urlset['path'] . $urlset['query']);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
@curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
//@curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_2_0);
if ($post) {
if (is_array($post)) {
$filepost = false;
foreach ($post as $name => &$value) {
if (version_compare(phpversion(), '5.6') >= 0 && substr($value, 0, 1) == '@') {
$value = new CURLFile(ltrim($value, '@'));
if (version_compare(phpversion(), '7.4.3') == 0) {
return dr_return_data(0, ' 本功能无法在php7.4.3中运行,请升级到php7.4.3以后的版本');
}
}
if ((is_string($value) && substr($value, 0, 1) == '@') || (class_exists('CURLFile') && $value instanceof CURLFile)) {
$filepost = true;
}
}
if (!$filepost) {
$post = http_build_query($post);
}
}
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
}
if (!empty($GLOBALS['_W']['config']['setting']['proxy'])) {
$urls = parse_url($GLOBALS['_W']['config']['setting']['proxy']['host']);
if (!empty($urls['host'])) {
curl_setopt($ch, CURLOPT_PROXY, "{$urls['host']}:{$urls['port']}");
$proxytype = 'CURLPROXY_' . strtoupper($urls['scheme']);
if (!empty($urls['scheme']) && defined($proxytype)) {
curl_setopt($ch, CURLOPT_PROXYTYPE, constant($proxytype));
} else {
curl_setopt($ch, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
curl_setopt($ch, CURLOPT_HTTPPROXYTUNNEL, 1);
}
if (!empty($GLOBALS['_W']['config']['setting']['proxy']['auth'])) {
curl_setopt($ch, CURLOPT_PROXYUSERPWD, $GLOBALS['_W']['config']['setting']['proxy']['auth']);
}
}
}
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
if (defined('CURL_SSLVERSION_TLSv1')) {
curl_setopt($ch, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1);
}
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 6.1; WOW64; rv:9.0.1) Gecko/20100101 Firefox/9.0.1');
if (!empty($extra) && is_array($extra)) {
$headers = array();
foreach ($extra as $opt => $value) {
if (strexists($opt, 'CURLOPT_')) {
curl_setopt($ch, constant($opt), $value);
} elseif (is_numeric($opt)) {
curl_setopt($ch, $opt, $value);
} else {
$headers[] = "{$opt}: {$value}";
}
}
if (!empty($headers)) {
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
}
}
$data = curl_exec($ch);
$status = curl_getinfo($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno || empty($data)) {
return dr_return_data(0, '同步出错:'.$error);
} else {
return ihttp_response_parse($data);
}
}
$method = empty($post) ? 'GET' : 'POST';
$fdata = "{$method} {$urlset['path']}{$urlset['query']} HTTP/1.1\r\n";
$fdata .= "Host: {$urlset['host']}\r\n";
if (function_exists('gzdecode')) {
$fdata .= "Accept-Encoding: gzip, deflate\r\n";
}
$fdata .= "Connection: close\r\n";
if (!empty($extra) && is_array($extra)) {
foreach ($extra as $opt => $value) {
if (!strexists($opt, 'CURLOPT_')) {
$fdata .= "{$opt}: {$value}\r\n";
}
}
}
$body = '';
if ($post) {
if (is_array($post)) {
$body = http_build_query($post);
} else {
$body = urlencode($post);
}
$fdata .= 'Content-Length: ' . strlen($body) . "\r\n\r\n{$body}";
} else {
$fdata .= "\r\n";
}
if ($urlset['scheme'] == 'https') {
$fp = fsockopen('ssl://' . $urlset['host'], $urlset['port'], $errno, $error);
} else {
$fp = fsockopen($urlset['host'], $urlset['port'], $errno, $error);
}
stream_set_blocking($fp, true);
stream_set_timeout($fp, $timeout);
if (!$fp) {
return dr_return_data(0, '同步出错:'.$error);
} else {
fwrite($fp, $fdata);
$content = '';
while (!feof($fp))
$content .= fgets($fp, 512);
fclose($fp);
return ihttp_response_parse($content, true);
}
}
function ihttp_response_parse($data, $chunked = false) {
$rlt = array();
$headermeta = explode('HTTP/', $data);
if (count($headermeta) > 2) {
$data = 'HTTP/' . array_pop($headermeta);
}
$pos = strpos($data, "\r\n\r\n");
$split1[0] = substr($data, 0, $pos);
$split1[1] = substr($data, $pos + 4, strlen($data));
$split2 = explode("\r\n", $split1[0], 2);
preg_match('/^(\S+) (\S+) (.*)$/', $split2[0], $matches);
$rlt['code'] = $matches[2];
$rlt['status'] = $matches[3];
$rlt['responseline'] = $split2[0];
$header = explode("\r\n", $split2[1]);
$isgzip = false;
$ischunk = false;
foreach ($header as $v) {
$pos = strpos($v, ':');
$key = substr($v, 0, $pos);
$value = trim(substr($v, $pos + 1));
if (is_array($rlt['headers'][$key])) {
$rlt['headers'][$key][] = $value;
} elseif (!empty($rlt['headers'][$key])) {
$temp = $rlt['headers'][$key];
unset($rlt['headers'][$key]);
$rlt['headers'][$key][] = $temp;
$rlt['headers'][$key][] = $value;
} else {
$rlt['headers'][$key] = $value;
}
if(!$isgzip && strtolower($key) == 'content-encoding' && strtolower($value) == 'gzip') {
$isgzip = true;
}
if(!$ischunk && strtolower($key) == 'transfer-encoding' && strtolower($value) == 'chunked') {
$ischunk = true;
}
}
if($chunked && $ischunk) {
$rlt['content'] = ihttp_response_parse_unchunk($split1[1]);
} else {
$rlt['content'] = $split1[1];
}
if($isgzip && function_exists('gzdecode')) {
$rlt['content'] = gzdecode($rlt['content']);
}
$rlt['meta'] = $data;
if($rlt['code'] == '100') {
return ihttp_response_parse($rlt['content']);
}
$data = json_decode($rlt['content'], true);
if (!$data) {
if($rlt['code'] != '200' && $rlt['status']) {
return dr_return_data(0, $rlt['status']);
}
return dr_return_data(0, $rlt['content'].'不是一个有效的json数据');
} elseif (isset($data['errcode']) && $data['errcode']) {
return dr_return_data(0, '错误代码('.dr_weixin_error_msg($data['errcode']).'):'.$data['errmsg']);
}
return dr_return_data(1, 'ok', $data);
}
function strexists($string, $find) {
return !(strpos($string, $find) === FALSE);
}
/**
*
* 通过code从工作平台获取openid机器access_token
* @param string $code 微信跳转回来带上的code
*
* @return openid
*/
function weixin_GetOpenidFromMp($code)
{
$url = weixin_CreateOauthUrlForOpenid($code);
//初始化curl
$ch = curl_init();
//设置超时
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER,FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST,FALSE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
//运行curl,结果以jason形式返回
$res = curl_exec($ch);
curl_close($ch);
//取出openid
$data = json_decode($res,true);
$openid = $data['openid'];
return $openid;
}
/**
*
* 构造获取code的url连接
* @param string $redirectUrl 微信服务器回跳的url,需要url编码
*
* @return 返回构造好的url
*/
function weixin_CreateOauthUrlForCode($redirectUrl)
{
$wx = \Phpcmf\Service::C()->get_cache('weixin'.(WEIXIN_MORE_ID > 1 ? '_more_'.WEIXIN_MORE_ID : '')); // 配置
$urlObj["appid"] = $wx['account']['appid'];
$urlObj["redirect_uri"] = "$redirectUrl";
$urlObj["response_type"] = "code";
$urlObj["scope"] = "snsapi_base";
$urlObj["state"] = "STATE"."#wechat_redirect";
$bizString = weixin_ToUrlParams($urlObj);
return "https://open.weixin.qq.com/connect/oauth2/authorize?".$bizString;
}
/**
*
* 构造获取open和access_toke的url地址
* @param string $code,微信跳转带回的code
*
* @return 请求的url
*/
function weixin_CreateOauthUrlForOpenid($code)
{
$wx = \Phpcmf\Service::C()->get_cache('weixin'.(WEIXIN_MORE_ID > 1 ? '_more_'.WEIXIN_MORE_ID : '')); // 配置
$urlObj["appid"] = $wx['account']['appid'];
$urlObj["secret"] = $wx['account']['appsecret'];
$urlObj["code"] = $code;
$urlObj["grant_type"] = "authorization_code";
$bizString = weixin_ToUrlParams($urlObj);
return "https://api.weixin.qq.com/sns/oauth2/access_token?".$bizString;
}
/**
*
* 拼接签名字符串
* @param array $urlObj
*
* @return 返回已经拼接好的字符串
*/
function weixin_ToUrlParams($urlObj)
{
$buff = "";
foreach ($urlObj as $k => $v)
{
if($k != "sign"){
$buff .= $k . "=" . $v . "&";
}
}
$buff = trim($buff, "&");
return $buff;
}
// 从url获取json数据
function wx_get_https_json_data($url, $ct = 0) {
if (!$url) {
return dr_return_data(0, 'url为空');
}
$response = dr_catcher_data($url);
$data = json_decode($response, true);
if (!$data) {
return dr_return_data(0, var_export($response, true).' 不是一个有效的json数据');
} elseif (isset($data['errcode']) && $data['errcode']) {
if ($data['errcode'] == '40001' && $ct == 0 && strpos($url, 'access_token=')) {
// 重新获取token
list($a, $b) = explode('access_token=', $url);
if (strpos($b, '&') !== false) {
list($b) = explode('&', $b);
}
$rt = weixin_get_access_token('update');
if ($rt['code']) {
return wx_get_https_json_data(str_replace($b, $rt['msg'], $url), 1);
}
}
return dr_return_data(0, '错误代码('.$data['errcode'].'):'.$data['errmsg']);
}
return dr_return_data(1, 'ok', $data);
}
// 从url获取json数据
function wx_post_https_json_data($url, $param = [], $ct = 0) {
$rt = dr_post_json_data($url, json_encode($param, JSON_UNESCAPED_UNICODE));
if ($rt['code']) {
if (isset($rt['data']['errcode']) && $rt['data']['errcode']) {
if ($rt['data']['errcode'] == '40001' && $ct == 0 && strpos($url, 'access_token=')) {
// 重新获取token
list($a, $b) = explode('access_token=', $url);
if (strpos($b, '&') !== false) {
list($b) = explode('&', $b);
}
$rt = weixin_get_access_token('update');
if ($rt['code']) {
return wx_post_https_json_data(str_replace($b, $rt['msg'], $url), $param, 1);
}
}
return dr_return_data(0, '错误代码('.dr_weixin_error_msg($rt['data']['errcode']).'):'.$rt['data']['errmsg']);
}
}
return $rt;
}
// 微信端的错误码转
function dr_weixin_error_msg($code) {
if ($code == '40001') {
// 清除掉token
\Phpcmf\Service::L('cache')->del_auth_data('weixin_access_token_'.(WEIXIN_MORE_ID > 1 ? '_more_'.WEIXIN_MORE_ID : ''), 1);
}
return $code;
}