2032 lines
56 KiB
PHP
2032 lines
56 KiB
PHP
<?php
|
||
// +----------------------------------------------------------------------
|
||
// | 小说系统 [ WE CAN DO IT JUST THINK IT ]
|
||
// +----------------------------------------------------------------------
|
||
use Wechat\Loader;
|
||
use \think\Db;
|
||
use think\Config;
|
||
use \think\Request;
|
||
use \think\Session;
|
||
use wxopen\WxComponentService;
|
||
use Firebase\JWT\JWT;
|
||
use Firebase\JWT\Key;
|
||
|
||
//常量定义
|
||
define('CMS_VERSION', '1.0');
|
||
|
||
|
||
|
||
//字符串解密加密
|
||
function authcode($string, $operation = 'DECODE', $key = '', $expiry = 0)
|
||
{
|
||
$ckey_length = 4; // 随机密钥长度 取值 0-32;
|
||
// 加入随机密钥,可以令密文无任何规律,即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。
|
||
// 取值越大,密文变动规律越大,密文变化 = 16 的 $ckey_length 次方
|
||
// 当此值为 0 时,则不产生随机密钥
|
||
$uc_key = config('data_auth_key') ? config('data_auth_key') : 'sentcms';
|
||
$key = md5($key ? $key : $uc_key);
|
||
$keya = md5(substr($key, 0, 16));
|
||
$keyb = md5(substr($key, 16, 16));
|
||
$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length) : substr(md5(microtime()), -$ckey_length)) : '';
|
||
|
||
$cryptkey = $keya . md5($keya . $keyc);
|
||
$key_length = strlen($cryptkey);
|
||
|
||
$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
|
||
|
||
$string_length = strlen($string);
|
||
$result = '';
|
||
$box = range(0, 255);
|
||
$rndkey = array();
|
||
for ($i = 0; $i <= 255; $i++) {
|
||
$rndkey[$i] = ord($cryptkey[$i % $key_length]);
|
||
}
|
||
|
||
for ($j = $i = 0; $i < 256; $i++) {
|
||
$j = ($j + $box[$i] + $rndkey[$i]) % 256;
|
||
$tmp = $box[$i];
|
||
$box[$i] = $box[$j];
|
||
$box[$j] = $tmp;
|
||
}
|
||
|
||
for ($a = $j = $i = 0; $i < $string_length; $i++) {
|
||
$a = ($a + 1) % 256;
|
||
$j = ($j + $box[$a]) % 256;
|
||
$tmp = $box[$a];
|
||
$box[$a] = $box[$j];
|
||
$box[$j] = $tmp;
|
||
$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
|
||
}
|
||
|
||
if ($operation == 'DECODE') {
|
||
if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
|
||
return substr($result, 26);
|
||
} else {
|
||
return '';
|
||
}
|
||
} else {
|
||
return $keyc . str_replace('=', '', base64_encode($result));
|
||
}
|
||
}
|
||
|
||
/**
|
||
+----------------------------------------------------------
|
||
* 产生随机字串,可用来自动生成密码 默认长度6位 字母和数字混合
|
||
+----------------------------------------------------------
|
||
* @param string $len 长度
|
||
* @param string $type 字串类型
|
||
* 0 字母 1 数字 其它 混合
|
||
* @param string $addChars 额外字符
|
||
+----------------------------------------------------------
|
||
* @return string
|
||
+----------------------------------------------------------
|
||
*/
|
||
function rand_string($len = 6, $type = '', $addChars = '')
|
||
{
|
||
$str = '';
|
||
switch ($type) {
|
||
case 0:
|
||
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz' . $addChars;
|
||
break;
|
||
case 1:
|
||
$chars = str_repeat('0123456789', 3);
|
||
break;
|
||
case 2:
|
||
$chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' . $addChars;
|
||
break;
|
||
case 3:
|
||
$chars = 'abcdefghijklmnopqrstuvwxyz' . $addChars;
|
||
break;
|
||
case 4:
|
||
$chars = "们以我到他会作时要动国产的一是工就年阶义发成部民可出能方进在了不和有大这主中人上为来分生对于学下级地个用同行面说种过命度革而多子后自社加小机也经力线本电高量长党得实家定深法表着水理化争现所二起政三好十战无农使性前等反体合斗路图把结第里正新开论之物从当两些还天资事队批点育重其思与间内去因件日利相由压员气业代全组数果期导平各基或月毛然如应形想制心样干都向变关问比展那它最及外没看治提五解系林者米群头意只明四道马认次文通但条较克又公孔领军流入接席位情运器并飞原油放立题质指建区验活众很教决特此常石强极土少已根共直团统式转别造切九你取西持总料连任志观调七么山程百报更见必真保热委手改管处己将修支识病象几先老光专什六型具示复安带每东增则完风回南广劳轮科北打积车计给节做务被整联步类集号列温装即毫知轴研单色坚据速防史拉世设达尔场织历花受求传口断况采精金界品判参层止边清至万确究书术状厂须离再目海交权且儿青才证低越际八试规斯近注办布门铁需走议县兵固除般引齿千胜细影济白格效置推空配刀叶率述今选养德话查差半敌始片施响收华觉备名红续均药标记难存测士身紧液派准斤角降维板许破述技消底床田势端感往神便贺村构照容非搞亚磨族火段算适讲按值美态黄易彪服早班麦削信排台声该击素张密害侯草何树肥继右属市严径螺检左页抗苏显苦英快称坏移约巴材省黑武培著河帝仅针怎植京助升王眼她抓含苗副杂普谈围食射源例致酸旧却充足短划剂宣环落首尺波承粉践府鱼随考刻靠够满夫失包住促枝局菌杆周护岩师举曲春元超负砂封换太模贫减阳扬江析亩木言球朝医校古呢稻宋听唯输滑站另卫字鼓刚写刘微略范供阿块某功套友限项余倒卷创律雨让骨远帮初皮播优占死毒圈伟季训控激找叫云互跟裂粮粒母练塞钢顶策双留误础吸阻故寸盾晚丝女散焊功株亲院冷彻弹错散商视艺灭版烈零室轻血倍缺厘泵察绝富城冲喷壤简否柱李望盘磁雄似困巩益洲脱投送奴侧润盖挥距触星松送获兴独官混纪依未突架宽冬章湿偏纹吃执阀矿寨责熟稳夺硬价努翻奇甲预职评读背协损棉侵灰虽矛厚罗泥辟告卵箱掌氧恩爱停曾溶营终纲孟钱待尽俄缩沙退陈讨奋械载胞幼哪剥迫旋征槽倒握担仍呀鲜吧卡粗介钻逐弱脚怕盐末阴丰雾冠丙街莱贝辐肠付吉渗瑞惊顿挤秒悬姆烂森糖圣凹陶词迟蚕亿矩康遵牧遭幅园腔订香肉弟屋敏恢忘编印蜂急拿扩伤飞露核缘游振操央伍域甚迅辉异序免纸夜乡久隶缸夹念兰映沟乙吗儒杀汽磷艰晶插埃燃欢铁补咱芽永瓦倾阵碳演威附牙芽永瓦斜灌欧献顺猪洋腐请透司危括脉宜笑若尾束壮暴企菜穗楚汉愈绿拖牛份染既秋遍锻玉夏疗尖殖井费州访吹荣铜沿替滚客召旱悟刺脑措贯藏敢令隙炉壳硫煤迎铸粘探临薄旬善福纵择礼愿伏残雷延烟句纯渐耕跑泽慢栽鲁赤繁境潮横掉锥希池败船假亮谓托伙哲怀割摆贡呈劲财仪沉炼麻罪祖息车穿货销齐鼠抽画饲龙库守筑房歌寒喜哥洗蚀废纳腹乎录镜妇恶脂庄擦险赞钟摇典柄辩竹谷卖乱虚桥奥伯赶垂途额壁网截野遗静谋弄挂课镇妄盛耐援扎虑键归符庆聚绕摩忙舞遇索顾胶羊湖钉仁音迹碎伸灯避泛亡答勇频皇柳哈揭甘诺概宪浓岛袭谁洪谢炮浇斑讯懂灵蛋闭孩释乳巨徒私银伊景坦累匀霉杜乐勒隔弯绩招绍胡呼痛峰零柴簧午跳居尚丁秦稍追梁折耗碱殊岗挖氏刃剧堆赫荷胸衡勤膜篇登驻案刊秧缓凸役剪川雪链渔啦脸户洛孢勃盟买杨宗焦赛旗滤硅炭股坐蒸凝竟陷枪黎救冒暗洞犯筒您宋弧爆谬涂味津臂障褐陆啊健尊豆拔莫抵桑坡缝警挑污冰柬嘴啥饭塑寄赵喊垫丹渡耳刨虎笔稀昆浪萨茶滴浅拥穴覆伦娘吨浸袖珠雌妈紫戏塔锤震岁貌洁剖牢锋疑霸闪埔猛诉刷狠忽灾闹乔唐漏闻沈熔氯荒茎男凡抢像浆旁玻亦忠唱蒙予纷捕锁尤乘乌智淡允叛畜俘摸锈扫毕璃宝芯爷鉴秘净蒋钙肩腾枯抛轨堂拌爸循诱祝励肯酒绳穷塘燥泡袋朗喂铝软渠颗惯贸粪综墙趋彼届墨碍启逆卸航衣孙龄岭骗休借" . $addChars;
|
||
break;
|
||
default:
|
||
// 默认去掉了容易混淆的字符oOLl和数字01,要添加请使用addChars参数
|
||
$chars = 'ABCDEFGHIJKMNPQRSTUVWXYZabcdefghijkmnpqrstuvwxyz23456789' . $addChars;
|
||
break;
|
||
}
|
||
if ($len > 10) {
|
||
//位数过长重复字符串一定次数
|
||
$chars = $type == 1 ? str_repeat($chars, $len) : str_repeat($chars, 5);
|
||
}
|
||
if ($type != 4) {
|
||
$chars = str_shuffle($chars);
|
||
$str = substr($chars, 0, $len);
|
||
} else {
|
||
// 中文随机字
|
||
for ($i = 0; $i < $len; $i++) {
|
||
$str .= msubstr($chars, floor(mt_rand(0, mb_strlen($chars, 'utf-8') - 1)), 1);
|
||
}
|
||
}
|
||
return $str;
|
||
}
|
||
|
||
/**
|
||
* 字符串截取,支持中文和其他编码
|
||
* @static
|
||
* @access public
|
||
* @param string $str 需要转换的字符串
|
||
* @param string $start 开始位置
|
||
* @param string $length 截取长度
|
||
* @param string $charset 编码格式
|
||
* @param string $suffix 截断显示字符
|
||
* @return string
|
||
*/
|
||
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
|
||
{
|
||
if (function_exists("mb_substr")) {
|
||
$slice = mb_substr($str, $start, $length, $charset);
|
||
} elseif (function_exists('iconv_substr')) {
|
||
$slice = iconv_substr($str, $start, $length, $charset);
|
||
if (false === $slice) {
|
||
$slice = '';
|
||
}
|
||
} else {
|
||
$re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
|
||
$re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
|
||
$re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
|
||
$re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
|
||
preg_match_all($re[$charset], $str, $match);
|
||
$slice = join("", array_slice($match[0], $start, $length));
|
||
}
|
||
if (strlen($slice) == strlen($str)) {
|
||
return $slice;
|
||
} else {
|
||
return $suffix ? $slice . '...' : $slice;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 处理插件钩子
|
||
* @param string $hook 钩子名称
|
||
* @param mixed $params 传入参数
|
||
* @return void
|
||
*/
|
||
function hook($hook, $params = array())
|
||
{
|
||
\think\Hook::listen($hook, $params);
|
||
}
|
||
|
||
/**
|
||
* 获取广告位广告
|
||
* @param string $name 广告位名称
|
||
* @param mixed $params 传入参数
|
||
* @return html
|
||
*/
|
||
function ad($name, $param = array())
|
||
{
|
||
return widget('common/Ad/run', array('name' => $name));
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 获取封面图片
|
||
* @param int $cover_id
|
||
* @param string $field
|
||
* @return 完整的数据 或者 指定的$field字段值
|
||
* @author huajie <banhuajie@163.com>
|
||
*/
|
||
function get_cover($cover_id, $field = null)
|
||
{
|
||
|
||
if (empty($cover_id)) {
|
||
return BASE_PATH . '/public/images/default.png';
|
||
}
|
||
$picture = db('Picture')->where(array('status' => 1, 'id' => $cover_id))->find();
|
||
|
||
if ($field == 'path') {
|
||
if (!empty($picture['url'])) {
|
||
$picture['path'] = $picture['url'] ? BASE_PATH . $picture['url'] : BASE_PATH . '/public/images/default.png';
|
||
} else {
|
||
$picture['path'] = $picture['path'] ? BASE_PATH . $picture['path'] : BASE_PATH . '/public/images/default.png';
|
||
}
|
||
}
|
||
return empty($field) ? $picture : $picture[$field];
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取多图地址
|
||
* @param array $covers
|
||
* @return 返回图片列表
|
||
* @author molong <molong@tensent.cn>
|
||
*/
|
||
function get_cover_list($covers)
|
||
{
|
||
if ($covers == '') {
|
||
return false;
|
||
}
|
||
$cover_list = explode(',', $covers);
|
||
foreach ($cover_list as $item) {
|
||
$list[] = get_cover($item, 'path');
|
||
}
|
||
return $list;
|
||
}
|
||
|
||
/**
|
||
* 字符串命名风格转换
|
||
* type 0 将Java风格转换为C的风格 1 将C风格转换为Java的风格
|
||
* @param string $name 字符串
|
||
* @param integer $type 转换类型
|
||
* @return string
|
||
*/
|
||
function parse_name($name, $type = 0)
|
||
{
|
||
if ($type) {
|
||
return ucfirst(preg_replace_callback('/_([a-zA-Z])/', function ($match) {
|
||
return strtoupper($match[1]);
|
||
}, $name));
|
||
} else {
|
||
return strtolower(trim(preg_replace("/[A-Z]/", "_\\0", $name), "_"));
|
||
}
|
||
}
|
||
|
||
// 不区分大小写的in_array实现
|
||
function in_array_case($value, $array)
|
||
{
|
||
return in_array(strtolower($value), array_map('strtolower', $array));
|
||
}
|
||
|
||
/**
|
||
* 数据签名认证
|
||
* @param array $data 被认证的数据
|
||
* @return string 签名
|
||
* @author 麦当苗儿 <zuojiazi@vip.qq.com>
|
||
*/
|
||
function data_auth_sign($data)
|
||
{
|
||
//数据类型检测
|
||
if (!is_array($data)) {
|
||
$data = (array) $data;
|
||
}
|
||
ksort($data); //排序
|
||
$code = http_build_query($data); //url编码并生成query字符串
|
||
$sign = sha1($code); //生成签名
|
||
return $sign;
|
||
}
|
||
|
||
/**
|
||
* 检测用户是否登录
|
||
* @return integer 0-未登录,大于0-当前登录用户ID
|
||
*/
|
||
function is_login()
|
||
{
|
||
$user = session('user_auth');
|
||
//file_put_contents(ROOT_PATH."user.log",json_encode($user).PHP_EOL,FILE_APPEND);
|
||
if (empty($user)) {
|
||
return 0;
|
||
} else {
|
||
return session('user_auth_sign') == data_auth_sign($user) ? $user['uid'] : 0;
|
||
}
|
||
}
|
||
|
||
|
||
|
||
/**
|
||
* 检测当前用户是否为管理员
|
||
* @return boolean true-管理员,false-非管理员
|
||
* @author 麦当苗儿 <zuojiazi@vip.qq.com>
|
||
*/
|
||
function is_administrator($uid = null)
|
||
{
|
||
$uid = is_null($uid) ? is_login() : $uid;
|
||
|
||
//return $uid && (intval($uid) === config('user_administrator'));
|
||
|
||
$user_administrator = db('member')->where(["status" => 1, "group" => 999])->column('uid');
|
||
return $uid && (in_array(intval($uid), $user_administrator));
|
||
}
|
||
|
||
/**
|
||
* 获取客户端IP地址
|
||
* @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
|
||
* @param boolean $adv 是否进行高级模式获取(有可能被伪装)
|
||
* @return mixed
|
||
*/
|
||
function get_client_ip($type = 0, $adv = false)
|
||
{
|
||
$type = $type ? 1 : 0;
|
||
static $ip = NULL;
|
||
if ($ip !== NULL) {
|
||
return $ip[$type];
|
||
}
|
||
|
||
if ($adv) {
|
||
if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
|
||
$arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
|
||
$pos = array_search('unknown', $arr);
|
||
if (false !== $pos) {
|
||
unset($arr[$pos]);
|
||
}
|
||
|
||
$ip = trim($arr[0]);
|
||
} elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
|
||
$ip = $_SERVER['HTTP_CLIENT_IP'];
|
||
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||
$ip = $_SERVER['REMOTE_ADDR'];
|
||
}
|
||
} elseif (isset($_SERVER['REMOTE_ADDR'])) {
|
||
$ip = $_SERVER['REMOTE_ADDR'];
|
||
}
|
||
// IP地址合法验证
|
||
$long = sprintf("%u", ip2long($ip));
|
||
$ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
|
||
return $ip[$type];
|
||
}
|
||
|
||
// 获取客户端ip 优化版
|
||
function get_real_ip()
|
||
{
|
||
$unknown = 'unknown';
|
||
if (isset($_SERVER['HTTP_X_FORWARDED_FOR']) && $_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], $unknown)) {
|
||
$ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
|
||
} elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], $unknown)) {
|
||
$ip = $_SERVER['REMOTE_ADDR'];
|
||
}
|
||
//处理多层代理的情况
|
||
$pos = strpos($ip, ',');
|
||
if ($pos === false) {
|
||
} else {
|
||
$ip = reset(explode(',', $ip));
|
||
}
|
||
return $ip;
|
||
}
|
||
|
||
// 获取对应充值用户的clickid
|
||
function getCid($uid, $ldurl)
|
||
{
|
||
$clickid = db('payclickid')->where(array(
|
||
'uid' => $uid,
|
||
'ldurl' => $ldurl
|
||
))->value('clickid');
|
||
return $clickid;
|
||
}
|
||
|
||
|
||
/**
|
||
* 时间戳格式化
|
||
* @param int $time
|
||
* @return string 完整的时间显示
|
||
* @author huajie <banhuajie@163.com>
|
||
*/
|
||
function time_format($time = NULL, $format = 'Y-m-d H:i')
|
||
{
|
||
$time = $time === NULL ? time() : intval($time);
|
||
return date($format, $time);
|
||
}
|
||
|
||
/**
|
||
* 根据用户ID获取用户名
|
||
* @param integer $uid 用户ID
|
||
* @return string 用户名
|
||
*/
|
||
function get_username($uid = 0)
|
||
{
|
||
static $list;
|
||
if (!($uid && is_numeric($uid))) {
|
||
//获取当前登录用户名
|
||
return session('user_auth.username');
|
||
}
|
||
$name = db('member')->where(array('uid' => $uid))->value('username');
|
||
return $name;
|
||
}
|
||
// 查询用户单字段数据
|
||
function get_userfield($uid = 0, $field = '')
|
||
{
|
||
if ($uid && $field) {
|
||
$res = db('member')->where(array('uid' => $uid))->value($field);
|
||
return $res;
|
||
}
|
||
}
|
||
|
||
/**
|
||
获取用户头像
|
||
*****/
|
||
|
||
function get_avatar($uid = 0)
|
||
{
|
||
static $list;
|
||
|
||
/* 获取缓存数据 */
|
||
if (empty($list)) {
|
||
$list = cache('sys_user_avatar_list');
|
||
}
|
||
|
||
/* 查找用户信息 */
|
||
$key = "u{$uid}";
|
||
if (isset($list[$key])) {
|
||
//已缓存,直接使用
|
||
$avatar = $list[$key];
|
||
} else {
|
||
//调用接口获取用户信息
|
||
$info = db('Member')->field('avatar')->find($uid);
|
||
if ($info !== false && $info['avatar']) {
|
||
if (strpos($info['avatar'], 'uploads') !== false) {
|
||
$avatar = str_replace('/uploads', config('web_site_url') . '/uploads', $info['avatar']);
|
||
} else {
|
||
$avatar = $info['avatar'];
|
||
}
|
||
|
||
$list[$key] = $avatar;
|
||
/* 缓存用户 */
|
||
$count = count($list);
|
||
$max = config('USER_MAX_CACHE');
|
||
while ($count-- > $max) {
|
||
array_shift($list);
|
||
}
|
||
cache('sys_user_avatar_list', $list);
|
||
} else {
|
||
$avatar = config('web_site_url') . "/uploads/avatar/1.jpg";
|
||
}
|
||
}
|
||
return $avatar;
|
||
}
|
||
/*****获取用户书币****/
|
||
function get_egold($uid)
|
||
{
|
||
$egold = db('Member')->where('uid', $uid)->value('egold');
|
||
return $egold;
|
||
}
|
||
/**
|
||
* 根据用户ID获取用户昵称
|
||
* @param integer $uid 用户ID
|
||
* @return string 用户昵称
|
||
*/
|
||
function get_nickname($uid = 0)
|
||
{
|
||
static $list;
|
||
if (!($uid && is_numeric($uid))) {
|
||
//获取当前登录用户名
|
||
return session('user_auth.username');
|
||
}
|
||
|
||
/* 获取缓存数据 */
|
||
if (empty($list)) {
|
||
$list = cache('sys_user_nickname_list');
|
||
}
|
||
|
||
/* 查找用户信息 */
|
||
$key = "u{$uid}";
|
||
if (isset($list[$key])) {
|
||
//已缓存,直接使用
|
||
$name = $list[$key];
|
||
} else {
|
||
//调用接口获取用户信息
|
||
$info = db('Member')->field('nickname')->find($uid);
|
||
if ($info !== false && $info['nickname']) {
|
||
$nickname = $info['nickname'];
|
||
$name = $list[$key] = $nickname;
|
||
/* 缓存用户 */
|
||
$count = count($list);
|
||
$max = config('USER_MAX_CACHE');
|
||
while ($count-- > $max) {
|
||
array_shift($list);
|
||
}
|
||
cache('sys_user_nickname_list', $list);
|
||
} else {
|
||
$name = db('member')->where(array('uid' => $uid))->value('username');
|
||
}
|
||
}
|
||
return $name;
|
||
}
|
||
|
||
/**
|
||
* 对查询结果集进行排序
|
||
* @access public
|
||
* @param array $list 查询结果
|
||
* @param string $field 排序的字段名
|
||
* @param array $sortby 排序类型
|
||
* asc正向排序 desc逆向排序 nat自然排序
|
||
* @return array
|
||
*/
|
||
function list_sort_by($list, $field, $sortby = 'asc')
|
||
{
|
||
if (is_array($list)) {
|
||
$refer = $resultSet = array();
|
||
foreach ($list as $i => $data) {
|
||
$refer[$i] = &$data[$field];
|
||
}
|
||
|
||
switch ($sortby) {
|
||
case 'asc': // 正向排序
|
||
asort($refer);
|
||
break;
|
||
case 'desc': // 逆向排序
|
||
arsort($refer);
|
||
break;
|
||
case 'nat': // 自然排序
|
||
natcasesort($refer);
|
||
break;
|
||
}
|
||
foreach ($refer as $key => $val) {
|
||
$resultSet[] = &$list[$key];
|
||
}
|
||
|
||
return $resultSet;
|
||
}
|
||
return false;
|
||
}
|
||
|
||
/**
|
||
* 把返回的数据集转换成Tree
|
||
* @param array $list 要转换的数据集
|
||
* @param string $pid parent标记字段
|
||
* @param string $level level标记字段
|
||
* @return array
|
||
* @author 麦当苗儿 <zuojiazi@vip.qq.com>
|
||
*/
|
||
function list_to_tree($list, $pk = 'id', $pid = 'pid', $child = '_child', $root = 0)
|
||
{
|
||
// 创建Tree
|
||
$tree = array();
|
||
if (is_array($list) && !is_object($list)) {
|
||
// 创建基于主键的数组引用
|
||
$refer = array();
|
||
foreach ($list as $key => $data) {
|
||
$refer[$data[$pk]] = &$list[$key];
|
||
}
|
||
foreach ($list as $key => $data) {
|
||
// 判断是否存在parent
|
||
$parentId = $data[$pid];
|
||
if ($root == $parentId) {
|
||
$tree[] = &$list[$key];
|
||
} else {
|
||
if (isset($refer[$parentId])) {
|
||
$parent = &$refer[$parentId];
|
||
$parent['childs'][] = $data['id'];
|
||
$parent[$child][] = &$list[$key];
|
||
}
|
||
}
|
||
}
|
||
}
|
||
return $tree;
|
||
}
|
||
|
||
/**
|
||
* 将list_to_tree的树还原成列表
|
||
* @param array $tree 原来的树
|
||
* @param string $child 孩子节点的键
|
||
* @param string $order 排序显示的键,一般是主键 升序排列
|
||
* @param array $list 过渡用的中间数组,
|
||
* @return array 返回排过序的列表数组
|
||
* @author yangweijie <yangweijiester@gmail.com>
|
||
*/
|
||
function tree_to_list($tree, $child = '_child', $order = 'id', &$list = array())
|
||
{
|
||
if (is_array($tree)) {
|
||
foreach ($tree as $key => $value) {
|
||
$reffer = $value;
|
||
if (isset($reffer[$child])) {
|
||
unset($reffer[$child]);
|
||
tree_to_list($value[$child], $child, $order, $list);
|
||
}
|
||
$list[] = $reffer;
|
||
}
|
||
$list = list_sort_by($list, $order, $sortby = 'asc');
|
||
}
|
||
return $list;
|
||
}
|
||
|
||
/**
|
||
* get_field [字段值转换]
|
||
*
|
||
* @param type $model_id [模型ID]
|
||
* @param type $fieldname [字段名]
|
||
* @param type $value [需要转化的值]
|
||
*
|
||
* @return type
|
||
**/
|
||
function get_field($model_id, $fieldname, $value)
|
||
{
|
||
$value = $value ? $value : 0;
|
||
$result = db('attribute')->where(array('model_id' => $model_id, 'name' => $fieldname))->field("extra")->cache(true)->find();
|
||
$attr = parse_field_attr($result["extra"]);
|
||
|
||
return $attr[$value];
|
||
}
|
||
|
||
// 分析枚举类型字段值 格式 a:名称1,b:名称2
|
||
// 暂时和 parse_config_attr功能相同
|
||
// 但请不要互相使用,后期会调整
|
||
function parse_field_attr($string)
|
||
{
|
||
if (0 === strpos($string, ':')) {
|
||
// 采用函数定义
|
||
return eval('return ' . substr($string, 1) . ';');
|
||
} elseif (0 === strpos($string, '[')) {
|
||
// 支持读取配置参数(必须是数组类型)
|
||
return \think\Config::get(substr($string, 1, -1));
|
||
}
|
||
|
||
$array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
|
||
if (strpos($string, ':')) {
|
||
$value = array();
|
||
foreach ($array as $val) {
|
||
list($k, $v) = explode(':', $val);
|
||
$value[$k] = $v;
|
||
}
|
||
} else {
|
||
$value = $array;
|
||
}
|
||
return $value;
|
||
}
|
||
|
||
function parse_field_bind($table, $selected = '', $model = 0)
|
||
{
|
||
|
||
|
||
$list = array();
|
||
if ($table) {
|
||
$res = db($table)->select();
|
||
foreach ($res as $key => $value) {
|
||
if (($model && isset($value['model_id']) && $value['model_id'] == $model)) {
|
||
$list[] = $value;
|
||
} elseif (!$model) {
|
||
$list[] = $value;
|
||
}
|
||
}
|
||
|
||
if (!empty($list)) {
|
||
$tree = new \com\Tree();
|
||
$list = $tree->toFormatTree($list);
|
||
}
|
||
}
|
||
return $list;
|
||
}
|
||
|
||
// 分析枚举类型配置值 格式 a:名称1,b:名称2
|
||
function parse_config_attr($string)
|
||
{
|
||
$array = preg_split('/[,;\r\n]+/', trim($string, ",;\r\n"));
|
||
if (strpos($string, ':')) {
|
||
$value = array();
|
||
foreach ($array as $val) {
|
||
list($k, $v) = explode(':', $val);
|
||
$value[$k] = $v;
|
||
}
|
||
} else {
|
||
$value = $array;
|
||
}
|
||
return $value;
|
||
}
|
||
|
||
function generate_password($length = 8)
|
||
{
|
||
// 密码字符集,可任意添加你需要的字符
|
||
$chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
|
||
|
||
$password = '';
|
||
for ($i = 0; $i < $length; $i++) {
|
||
// 这里提供两种字符获取方式
|
||
// 第一种是使用 substr 截取$chars中的任意一位字符;
|
||
// 第二种是取字符数组 $chars 的任意元素
|
||
// $password .= substr($chars, mt_rand(0, strlen($chars) - 1), 1);
|
||
$password .= $chars[mt_rand(0, strlen($chars) - 1)];
|
||
}
|
||
|
||
return $password;
|
||
}
|
||
|
||
/**
|
||
* 记录行为日志,并执行该行为的规则
|
||
* @param string $action 行为标识
|
||
* @param string $model 触发行为的模型名
|
||
* @param int $record_id 触发行为的记录id
|
||
* @param int $user_id 执行行为的用户id
|
||
* @return boolean
|
||
* @author huajie <banhuajie@163.com>
|
||
*/
|
||
function action_log($action = null, $model = null, $record_id = null, $user_id = null)
|
||
{
|
||
|
||
//参数检查
|
||
if (empty($action) || empty($model) || empty($record_id)) {
|
||
return '参数不能为空';
|
||
}
|
||
if (empty($user_id)) {
|
||
$user_id = is_login();
|
||
}
|
||
|
||
//查询行为,判断是否执行
|
||
$action_info = db('Action')->getByName($action);
|
||
if ($action_info['status'] != 1) {
|
||
return '该行为被禁用或删除';
|
||
}
|
||
|
||
//插入行为日志
|
||
$data['action_id'] = $action_info['id'];
|
||
$data['user_id'] = $user_id;
|
||
$data['action_ip'] = ip2long(get_client_ip());
|
||
$data['model'] = $model;
|
||
$data['record_id'] = $record_id;
|
||
$data['create_time'] = time();
|
||
|
||
//解析日志规则,生成日志备注
|
||
if (!empty($action_info['log'])) {
|
||
if (preg_match_all('/\[(\S+?)\]/', $action_info['log'], $match)) {
|
||
$log['user'] = $user_id;
|
||
$log['record'] = $record_id;
|
||
$log['model'] = $model;
|
||
$log['time'] = time();
|
||
$log['data'] = array('user' => $user_id, 'model' => $model, 'record' => $record_id, 'time' => time());
|
||
foreach ($match[1] as $value) {
|
||
$param = explode('|', $value);
|
||
if (isset($param[1])) {
|
||
$replace[] = call_user_func($param[1], $log[$param[0]]);
|
||
} else {
|
||
$replace[] = $log[$param[0]];
|
||
}
|
||
}
|
||
$data['remark'] = str_replace($match[0], $replace, $action_info['log']);
|
||
} else {
|
||
$data['remark'] = $action_info['log'];
|
||
}
|
||
} else {
|
||
//未定义日志规则,记录操作url
|
||
$data['remark'] = '操作url:' . $_SERVER['REQUEST_URI'];
|
||
}
|
||
|
||
db('ActionLog')->insert($data);
|
||
|
||
if (!empty($action_info['rule'])) {
|
||
//解析行为
|
||
$rules = parse_action($action, $user_id);
|
||
|
||
//执行行为
|
||
$res = execute_action($rules, $action_info['id'], $user_id);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 解析行为规则
|
||
* 规则定义 table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......]
|
||
* 规则字段解释:table->要操作的数据表,不需要加表前缀;
|
||
* field->要操作的字段;
|
||
* condition->操作的条件,目前支持字符串,默认变量{$self}为执行行为的用户
|
||
* rule->对字段进行的具体操作,目前支持四则混合运算,如:1+score*2/2-3
|
||
* cycle->执行周期,单位(小时),表示$cycle小时内最多执行$max次
|
||
* max->单个周期内的最大执行次数($cycle和$max必须同时定义,否则无效)
|
||
* 单个行为后可加 ; 连接其他规则
|
||
* @param string $action 行为id或者name
|
||
* @param int $self 替换规则里的变量为执行用户的id
|
||
* @return boolean|array: false解析出错 , 成功返回规则数组
|
||
* @author huajie <banhuajie@163.com>
|
||
*/
|
||
function parse_action($action = null, $self)
|
||
{
|
||
if (empty($action)) {
|
||
return false;
|
||
}
|
||
|
||
//参数支持id或者name
|
||
if (is_numeric($action)) {
|
||
$map = array('id' => $action);
|
||
} else {
|
||
$map = array('name' => $action);
|
||
}
|
||
|
||
//查询行为信息
|
||
$info = db('Action')->where($map)->find();
|
||
if (!$info || $info['status'] != 1) {
|
||
return false;
|
||
}
|
||
|
||
//解析规则:table:$table|field:$field|condition:$condition|rule:$rule[|cycle:$cycle|max:$max][;......]
|
||
$rules = $info['rule'];
|
||
$rules = str_replace('{$self}', $self, $rules);
|
||
$rules = explode(';', $rules);
|
||
$return = array();
|
||
foreach ($rules as $key => &$rule) {
|
||
$rule = explode('|', $rule);
|
||
foreach ($rule as $k => $fields) {
|
||
$field = empty($fields) ? array() : explode(':', $fields);
|
||
if (!empty($field)) {
|
||
$return[$key][$field[0]] = $field[1];
|
||
}
|
||
}
|
||
//cycle(检查周期)和max(周期内最大执行次数)必须同时存在,否则去掉这两个条件
|
||
if (!array_key_exists('cycle', $return[$key]) || !array_key_exists('max', $return[$key])) {
|
||
unset($return[$key]['cycle'], $return[$key]['max']);
|
||
}
|
||
}
|
||
|
||
return $return;
|
||
}
|
||
|
||
/**
|
||
* 执行行为
|
||
* @param array $rules 解析后的规则数组
|
||
* @param int $action_id 行为id
|
||
* @param array $user_id 执行的用户id
|
||
* @return boolean false 失败 , true 成功
|
||
* @author huajie <banhuajie@163.com>
|
||
*/
|
||
function execute_action($rules = false, $action_id = null, $user_id = null)
|
||
{
|
||
if (!$rules || empty($action_id) || empty($user_id)) {
|
||
return false;
|
||
}
|
||
|
||
$return = true;
|
||
foreach ($rules as $rule) {
|
||
|
||
//检查执行周期
|
||
$map = array('action_id' => $action_id, 'user_id' => $user_id);
|
||
$map['create_time'] = array('gt', NOW_TIME - intval($rule['cycle']) * 3600);
|
||
$exec_count = db('ActionLog')->where($map)->count();
|
||
if ($exec_count > $rule['max']) {
|
||
continue;
|
||
}
|
||
|
||
//执行数据库操作
|
||
$Model = db(ucfirst($rule['table']));
|
||
$field = $rule['field'];
|
||
$res = $Model->where($rule['condition'])->setField($field, array('exp', $rule['rule']));
|
||
|
||
if (!$res) {
|
||
$return = false;
|
||
}
|
||
}
|
||
return $return;
|
||
}
|
||
|
||
function avatar($uid, $size = 'middle')
|
||
{
|
||
$size = in_array($size, array('big', 'middle', 'small', 'real')) ? $size : 'middle';
|
||
$dir = setavatardir($uid);
|
||
$file = BASE_PATH . '/uploads/avatar/' . $dir . 'avatar_' . $size . '.png';
|
||
if (!file_exists('.' . $file)) {
|
||
$file = BASE_PATH . '/public/images/default_avatar_' . $size . '.jpg';
|
||
}
|
||
return $file;
|
||
}
|
||
|
||
function setavatardir($uid)
|
||
{
|
||
$uid = abs(intval($uid));
|
||
$uid = sprintf("%09d", $uid);
|
||
$dir1 = substr($uid, 0, 3);
|
||
$dir2 = substr($uid, 3, 2);
|
||
$dir3 = substr($uid, 5, 2);
|
||
$dir4 = substr($uid, 7, 2);
|
||
$dir = $dir1 . '/' . $dir2 . '/' . $dir3 . '/' . $dir4 . '/';
|
||
if (!is_dir("./uploads/avatar/$dir")) {
|
||
mk_dir("./uploads/avatar/" . $dir);
|
||
}
|
||
return $dir;
|
||
}
|
||
|
||
function mk_dir($dir, $mode = 0755)
|
||
{
|
||
if (is_dir($dir) || @mkdir($dir, $mode, true)) {
|
||
return true;
|
||
}
|
||
|
||
if (!mk_dir(dirname($dir), $mode, true)) {
|
||
return false;
|
||
}
|
||
|
||
return @mkdir($dir, $mode, true);
|
||
}
|
||
|
||
/**
|
||
* 字符串转换为数组,主要用于把分隔符调整到第二个参数
|
||
* @param string $str 要分割的字符串
|
||
* @param string $glue 分割符
|
||
* @return array
|
||
* @author 麦当苗儿 <zuojiazi@vip.qq.com>
|
||
*/
|
||
function str2arr($str = '', $glue = ',')
|
||
{
|
||
if ($str) {
|
||
return explode($glue, $str);
|
||
} else {
|
||
return array();
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 数组转换为字符串,主要用于把分隔符调整到第二个参数
|
||
* @param array $arr 要连接的数组
|
||
* @param string $glue 分割符
|
||
* @return string
|
||
* @author 麦当苗儿 <zuojiazi@vip.qq.com>
|
||
*/
|
||
function arr2str($arr = array(), $glue = ',')
|
||
{
|
||
if (empty($arr)) {
|
||
return '';
|
||
} else {
|
||
return implode($glue, $arr);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* 格式化字节大小
|
||
* @param number $size 字节数
|
||
* @param string $delimiter 数字和单位分隔符
|
||
* @return string 格式化后的带单位的大小
|
||
* @author 麦当苗儿 <zuojiazi@vip.qq.com>
|
||
*/
|
||
function format_bytes($size, $delimiter = '')
|
||
{
|
||
$units = array('B', 'KB', 'MB', 'GB', 'TB', 'PB');
|
||
for ($i = 0; $size >= 1024 && $i < 5; $i++) {
|
||
$size /= 1024;
|
||
}
|
||
|
||
return round($size, 2) . $delimiter . $units[$i];
|
||
}
|
||
|
||
function get_grid_list($list_grids)
|
||
{
|
||
$grids = preg_split('/[;\r\n]+/s', trim($list_grids));
|
||
foreach ($grids as &$value) {
|
||
// 字段:标题:链接
|
||
$val = explode(':', $value);
|
||
// 支持多个字段显示
|
||
$field = explode(',', $val[0]);
|
||
$value = array('field' => $field, 'title' => $val[1]);
|
||
if (isset($val[2])) {
|
||
// 链接信息
|
||
$value['href'] = $val[2];
|
||
// 搜索链接信息中的字段信息
|
||
preg_replace_callback('/\[([a-z_]+)\]/', function ($match) use (&$fields) {
|
||
$fields[] = $match[1];
|
||
}, $value['href']);
|
||
}
|
||
if (strpos($val[1], '|')) {
|
||
// 显示格式定义
|
||
list($value['title'], $value['format']) = explode('|', $val[1]);
|
||
}
|
||
foreach ($field as $val) {
|
||
$array = explode('|', $val);
|
||
$fields[] = $array[0];
|
||
}
|
||
}
|
||
$data = array('grids' => $grids, 'fields' => $fields);
|
||
return $data;
|
||
}
|
||
|
||
// 获取属性类型信息
|
||
function get_attribute_type($type = '')
|
||
{
|
||
// TODO 可以加入系统配置
|
||
$type_array = config('config_type_list');
|
||
static $type_list = array();
|
||
foreach ($type_array as $key => $value) {
|
||
$type_list[$key] = explode(',', $value);
|
||
}
|
||
return $type ? $type_list[$type][0] : $type_list;
|
||
}
|
||
|
||
//获得内容状态
|
||
function get_content_status($status)
|
||
{
|
||
$text = array(
|
||
'-1' => '<span class="label label-danger">删除</span>',
|
||
'0' => '<span class="label label-default">禁用</span>',
|
||
'1' => '<span class="label label-primary">正常</span>',
|
||
'2' => '<span class="label label-info">待审核</span>',
|
||
);
|
||
return $text[$status];
|
||
}
|
||
|
||
/**
|
||
* 获取分类信息并缓存分类
|
||
* @param integer $id 分类ID
|
||
* @param string $field 要获取的字段名
|
||
* @return string 分类信息
|
||
*/
|
||
function get_category($id, $field = null)
|
||
{
|
||
/* 非法分类ID */
|
||
if (empty($id) || !is_numeric($id)) {
|
||
return '';
|
||
}
|
||
$list = cache('category_list' . $id);
|
||
/* 读取缓存数据 */
|
||
if (empty($list)) {
|
||
$list = db('Category')->find($id);
|
||
cache('category_list' . $id, $list);
|
||
}
|
||
|
||
return is_null($field) ? $list : $list[$field];
|
||
}
|
||
|
||
/* 根据ID获取分类标识 */
|
||
function get_category_name($id)
|
||
{
|
||
return get_category($id, 'title');
|
||
}
|
||
|
||
/* 根据ID获取分类名称 */
|
||
function get_category_title($id)
|
||
{
|
||
return get_category($id, 'title');
|
||
}
|
||
|
||
//分类分组
|
||
function get_category_list_tree($model)
|
||
{
|
||
$list = cache('sys_category_list');
|
||
|
||
/* 读取缓存数据 */
|
||
if (empty($list)) {
|
||
$list = db('Category')->select();
|
||
cache('sys_category_list', $list);
|
||
}
|
||
if ($model) {
|
||
foreach ($list as $key => $value) {
|
||
$models = explode(',', $value['model']);
|
||
if (in_array($model, $models)) {
|
||
$res[] = $value;
|
||
}
|
||
}
|
||
} else {
|
||
$res = $list;
|
||
}
|
||
|
||
$tree = list_to_tree($res);
|
||
return $tree;
|
||
}
|
||
|
||
//获取栏目子ID
|
||
function get_category_child($id)
|
||
{
|
||
$list = cache('sys_category_list');
|
||
|
||
/* 读取缓存数据 */
|
||
if (empty($list)) {
|
||
$list = db('category')->select();
|
||
cache('sys_category_list', $list);
|
||
}
|
||
$ids[] = $id;
|
||
foreach ($list as $key => $value) {
|
||
if ($value['pid'] == $id) {
|
||
$ids[] = $value['id'];
|
||
$ids = array_merge($ids, get_category_child($value['id']));
|
||
}
|
||
}
|
||
return array_unique($ids);
|
||
}
|
||
|
||
function send_email($to, $subject, $message)
|
||
{
|
||
$config = array(
|
||
'protocol' => 'smtp',
|
||
'smtp_host' => \think\Config::get('mail_host'),
|
||
'smtp_user' => \think\Config::get('mail_username'),
|
||
'smtp_pass' => \think\Config::get('mail_password'),
|
||
);
|
||
$email = new \com\Email($config);
|
||
$email->from(\think\Config::get('mail_fromname'), \think\Config::get('web_site_title'));
|
||
$email->to($to);
|
||
|
||
$email->subject($subject);
|
||
$email->message($message);
|
||
|
||
return $email->send();
|
||
}
|
||
|
||
//实例化模型
|
||
function M($name, $type = 'model')
|
||
{
|
||
if ($type == 'model') {
|
||
return new \app\common\model\Content(strtolower($name));
|
||
} elseif ($type == 'form') {
|
||
return new \app\common\model\DiyForm(strtolower($name));
|
||
}
|
||
}
|
||
|
||
//php获取中文字符拼音首字母
|
||
function getFirstCharter($s0)
|
||
{
|
||
|
||
$fchar = ord($s0{
|
||
0});
|
||
if ($fchar >= ord("A") and $fchar <= ord("z")) {
|
||
return strtoupper($s0{
|
||
0});
|
||
}
|
||
|
||
$s1 = \iconv("UTF-8", "gb2312", $s0);
|
||
$s2 = \iconv("gb2312", "UTF-8", $s1);
|
||
if ($s2 == $s0) {
|
||
$s = $s1;
|
||
} else {
|
||
$s = $s0;
|
||
}
|
||
$asc = ord($s{
|
||
0}) * 256 + ord($s{
|
||
1}) - 65536;
|
||
if ($asc >= -20319 and $asc <= -20284) {
|
||
return "A";
|
||
}
|
||
|
||
if ($asc >= -20283 and $asc <= -19776) {
|
||
return "B";
|
||
}
|
||
|
||
if ($asc >= -19775 and $asc <= -19219) {
|
||
return "C";
|
||
}
|
||
|
||
if ($asc >= -19218 and $asc <= -18711) {
|
||
return "D";
|
||
}
|
||
|
||
if ($asc >= -18710 and $asc <= -18527) {
|
||
return "E";
|
||
}
|
||
|
||
if ($asc >= -18526 and $asc <= -18240) {
|
||
return "F";
|
||
}
|
||
|
||
if ($asc >= -18239 and $asc <= -17923) {
|
||
return "G";
|
||
}
|
||
|
||
if ($asc >= -17922 and $asc <= -17418) {
|
||
return "H";
|
||
}
|
||
|
||
if ($asc >= -17417 and $asc <= -16475) {
|
||
return "J";
|
||
}
|
||
|
||
if ($asc >= -16474 and $asc <= -16213) {
|
||
return "K";
|
||
}
|
||
|
||
if ($asc >= -16212 and $asc <= -15641) {
|
||
return "L";
|
||
}
|
||
|
||
if ($asc >= -15640 and $asc <= -15166) {
|
||
return "M";
|
||
}
|
||
|
||
if ($asc >= -15165 and $asc <= -14923) {
|
||
return "N";
|
||
}
|
||
|
||
if ($asc >= -14922 and $asc <= -14915) {
|
||
return "O";
|
||
}
|
||
|
||
if ($asc >= -14914 and $asc <= -14631) {
|
||
return "P";
|
||
}
|
||
|
||
if ($asc >= -14630 and $asc <= -14150) {
|
||
return "Q";
|
||
}
|
||
|
||
if ($asc >= -14149 and $asc <= -14091) {
|
||
return "R";
|
||
}
|
||
|
||
if ($asc >= -14090 and $asc <= -13319) {
|
||
return "S";
|
||
}
|
||
|
||
if ($asc >= -13318 and $asc <= -12839) {
|
||
return "T";
|
||
}
|
||
|
||
if ($asc >= -12838 and $asc <= -12557) {
|
||
return "W";
|
||
}
|
||
|
||
if ($asc >= -12556 and $asc <= -11848) {
|
||
return "X";
|
||
}
|
||
|
||
if ($asc >= -11847 and $asc <= -11056) {
|
||
return "Y";
|
||
}
|
||
|
||
if ($asc >= -11055 and $asc <= -10247) {
|
||
return "Z";
|
||
}
|
||
|
||
return null;
|
||
}
|
||
|
||
function PyFirst($zh)
|
||
{
|
||
$ret = "";
|
||
$s1 = \iconv("UTF-8", "gb2312", $zh);
|
||
$s2 = \iconv("gb2312", "UTF-8", $s1);
|
||
if ($s2 == $zh) {
|
||
$zh = $s1;
|
||
}
|
||
for ($i = 0; $i < strlen($zh); $i++) {
|
||
$s1 = substr($zh, $i, 1);
|
||
$p = ord($s1);
|
||
if ($p > 160) {
|
||
$s2 = substr($zh, $i++, 2);
|
||
$ret .= getFirstCharter($s2);
|
||
} else {
|
||
$ret .= $s1;
|
||
}
|
||
}
|
||
return $ret;
|
||
}
|
||
//获取对应表中的数据
|
||
function parse_field_data($string)
|
||
{
|
||
$rule = explode('|', $string);
|
||
//var_dump($rule);
|
||
foreach ($rule as $fields) {
|
||
$field = empty($fields) ? array() : explode(':', $fields);
|
||
if (!empty($field)) {
|
||
$rules[$field[0]] = $field[1];
|
||
}
|
||
}
|
||
$res = db(ucfirst($rules['table']))->field($rules['field'])->where($rules['condition'])->order($rules['order'])->cache(true)->select();
|
||
$value = array();
|
||
$fields = explode(',', $rules['field']);
|
||
foreach ($res as $val) {
|
||
$value[$val[$fields[0]]] = $val[$fields[1]];
|
||
}
|
||
return $value;
|
||
}
|
||
|
||
|
||
/**
|
||
* 根据条件字段获取数据
|
||
* @param mixed $value 条件,可用常量或者数组
|
||
* @param string $condition 条件字段
|
||
* @param string $field 需要返回的字段,不传则返回整个数据
|
||
*
|
||
*/
|
||
function get_document_field($model = 'Model', $value = null, $condition = 'id', $field = null)
|
||
{
|
||
if (empty($value)) {
|
||
return false;
|
||
}
|
||
|
||
//拼接参数
|
||
$map[$condition] = $value;
|
||
$info = db($model)->where($map);
|
||
if (empty($field)) {
|
||
$info = $info->field(true)->cache(true, 30)->find();
|
||
} else {
|
||
$info = $info->cache(true, 30)->value($field);
|
||
}
|
||
return $info;
|
||
}
|
||
|
||
/**
|
||
* get_new_chapter [获取最新章节]
|
||
*
|
||
* @param type $aid [desc]
|
||
* @param type $field [desc]
|
||
*
|
||
* @return type
|
||
**/
|
||
function get_new_chapter($bookid, $field = null)
|
||
{
|
||
if (empty($field)) {
|
||
|
||
$chapter = db('chapter')->where('articleid', $bookid)->order(' chapterorder DESC')->field('id,chaptername,update_time')->cache(true)->find();
|
||
} else {
|
||
$chapter = db('chapter')->where('articleid', $bookid)->order(' chapterorder DESC')->cache(true)->value($field);
|
||
}
|
||
|
||
return $chapter;
|
||
}
|
||
|
||
|
||
/**
|
||
* get_novel [获取小说信息]
|
||
*
|
||
* @param type $bookid [desc]
|
||
* @param type $field [desc]
|
||
*
|
||
* @return type
|
||
**/
|
||
function get_novel($bookid, $field = null)
|
||
{
|
||
|
||
if (empty($field)) {
|
||
$novel = db('novel')->where('id', $bookid)->cache(true)->find();
|
||
} else {
|
||
$novel = db('novel')->where('id', $bookid)->cache(true)->value($field);
|
||
if ($field == 'cover') {
|
||
if (empty($novel)) {
|
||
$novel = "/public/novel/images/default.jpg";
|
||
}
|
||
}
|
||
}
|
||
|
||
return $novel;
|
||
}
|
||
|
||
|
||
|
||
/****是否已加入书签*****/
|
||
function get_bookcase($bookid, $uid)
|
||
{
|
||
$info = db('bookcase')->where(['uid' => $uid, 'model' => 1, 'articleid' => $bookid])->find();
|
||
if ($info) {
|
||
return 1;
|
||
} else {
|
||
return 0;
|
||
}
|
||
}
|
||
/**
|
||
* 获取微信操作对象
|
||
* @staticvar array $wechat
|
||
* @param type $type
|
||
* @return WechatReceive
|
||
*/
|
||
function &load_wechat($uid, $type = '')
|
||
{
|
||
static $wechat = array();
|
||
//$uid = session('user_auth.uid');
|
||
$index = md5(strtolower($type));
|
||
if (!isset($wechat[$index])) {
|
||
$config = array(
|
||
'token' => 'mytoken', // 填写你设定的key
|
||
'appid' => Db::name('wxopen_account')->where(array('id' => $uid))->value('appid'), // 填写高级调用功能的app id, 请在微信开发模式后台查询
|
||
'appsecret' => Db::name('wxopen_account')->where(array('id' => $uid))->value('appsecret'), // 填写高级调用功能的密钥
|
||
'encodingaeskey' => '', // 填写加密用的EncodingAESKey(可选,接口传输选择加密时必需)
|
||
'mch_id' => '', // 微信支付,商户ID(可选)
|
||
'partnerkey' => '', // 微信支付,密钥(可选)
|
||
'ssl_cer' => '', // 微信支付,证书cert的路径(可选,操作退款或打款时必需)
|
||
'ssl_key' => '', // 微信支付,证书key的路径(可选,操作退款或打款时必需)
|
||
'cachepath' => ROOT_PATH . 'data/Wechat/', // 设置SDK缓存目录(可选,默认位置在./src/Cache下,请保证写权限)
|
||
);
|
||
$wechat[$index] = Loader::get($type, $config);
|
||
}
|
||
return $wechat[$index];
|
||
}
|
||
|
||
function get_cartoon_img($carttoon_id, $path = null)
|
||
{
|
||
$info = db('cartoon')->where('id', $carttoon_id)->find();
|
||
if (is_null($path)) {
|
||
$novel = get_cover($info['cartoonspic'], 'path');
|
||
} else {
|
||
$novel = get_cover($info[$path], 'path');
|
||
}
|
||
return $novel;
|
||
}
|
||
|
||
function get_novel_img($articleid, $path = 'cover')
|
||
{
|
||
$cover = db('novel')->where('id', $articleid)->value($path);
|
||
if (empty($cover)) {
|
||
return "/public/novel/images/default.jpg";
|
||
}
|
||
return $cover;
|
||
}
|
||
|
||
function getCartoonFiled($id, $filed)
|
||
{
|
||
$info = db('cartoon')->where($id)->find();
|
||
return $info[$filed];
|
||
}
|
||
/**判断是否为微信浏览器*/
|
||
function is_weixin()
|
||
{
|
||
if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
|
||
return true;
|
||
}
|
||
return false;
|
||
}
|
||
/**微信自动登录**/
|
||
function wxauto()
|
||
{
|
||
$host = explode('.', $_SERVER['HTTP_HOST']);
|
||
|
||
// 公众号ID 检测是否是其他公众号
|
||
$wx_config = false;
|
||
$wxid = request()->param('wxid');
|
||
if ($wxid) {
|
||
if ($wxid == 0) {
|
||
Session::delete('wxid');
|
||
} else {
|
||
session('wxid', $wxid);
|
||
$wx_config = true;
|
||
}
|
||
}
|
||
|
||
|
||
$url = config('web_site_url');
|
||
$appid = config('wx_apiid');
|
||
$apikey = config('wx_apikey'); //空值
|
||
$secretkey = config('wx_secretkey');
|
||
$login_type = 1; //授权登录
|
||
|
||
// 其他公众号
|
||
if ($wx_config) {
|
||
$upconfig = db('wxopen_account')->field('appid,appsecret')->where('id', $wxid)->find();
|
||
$appid = $upconfig['appid'];
|
||
$secretkey = $upconfig['appsecret'];
|
||
}
|
||
|
||
if ($login_type == 1) {
|
||
$type = 'wx_permission';
|
||
} else {
|
||
$type = 'wx_auto';
|
||
}
|
||
|
||
//登录成功后返回的地址
|
||
$jumpurl = "http://" . $_SERVER['HTTP_HOST'] . Request::instance()->url();
|
||
$wx_backurl = $jumpurl ? $jumpurl : Request::instance()->server('HTTP_REFERER');
|
||
|
||
|
||
session('host', $host);
|
||
session('backurl', $wx_backurl);
|
||
//定义接口类型
|
||
session('api_login_type', $type);
|
||
//多个域名的时候
|
||
|
||
if (strpos($host[0], 't') !== false) {
|
||
$uid = split_host($host[0]);
|
||
$wxmpid = split_host($host[0], 2);
|
||
$auto = db('wxmp')->where(['uid' => $uid, 'id' => $wxmpid])->field('id,appid,autoconfig,open_appid')->find();
|
||
|
||
//公众号自动配置
|
||
if (array_key_exists("autoconfig", $auto) && $auto["autoconfig"]) {
|
||
$account = db('wxopen_account')->where('appid', $auto['open_appid'])->find();
|
||
$wxComponentConfig = array(
|
||
'component_appid' => $account["appid"],
|
||
'component_appsecret' => $account["appsecret"],
|
||
'encodingAesKey' => $account["encodingKey"],
|
||
'token' => $account["token"]
|
||
);
|
||
$callbackurl = config('web_pc_url') . "/login/autocallback/component_appid/" . $account["appid"] . "/channel/" . $uid;
|
||
|
||
$wxAuth = new WxComponentService($wxComponentConfig);
|
||
if ($login_type == 1) {
|
||
$url = $wxAuth->getOauthRedirect($auto['appid'], $callbackurl, '234', 'snsapi_userinfo');
|
||
//公众号自动配置授权登录
|
||
session('api_login_type', 'wx_autopermission');
|
||
} else {
|
||
$url = $wxAuth->getOauthRedirect($auto['appid'], $callbackurl, '234', 'snsapi_base');
|
||
//公众号自动配置静默登录
|
||
session('api_login_type', 'wx_autoconfig');
|
||
}
|
||
header('location:' . $url);
|
||
exit();
|
||
} else {
|
||
$appid = db('wxmp')->where('uid', $uid)->value('appid');
|
||
$apikey = db('wxmp')->where('uid', $uid)->value('appsecret');
|
||
$secretkey = db('wxmp')->where('uid', $uid)->value('appsecret');
|
||
|
||
$callbackurl = "http://" . $_SERVER['HTTP_HOST'] . "/login/callback";
|
||
|
||
import('wxlogin.wxmp', EXTEND_PATH);
|
||
$weixin = new \Wxmp($appid, $apikey, $secretkey);
|
||
$weixin->CreateLoginUrl($callbackurl, $login_type);
|
||
}
|
||
} else {
|
||
$callbackurl = $url . "/login/callback";
|
||
import('wxlogin.wxmp', EXTEND_PATH);
|
||
$weixin = new \Wxmp($appid, $apikey, $secretkey);
|
||
$weixin->CreateLoginUrl($callbackurl, $login_type);
|
||
}
|
||
exit();
|
||
}
|
||
|
||
/****评论数*****/
|
||
function get_feedback($id, $model = 2)
|
||
{
|
||
if ($model == 2) {
|
||
return db('cartoon_feedback')->where(array('cartoon_id' => $id, 'status' => 1))->count();
|
||
} else {
|
||
return db('novel_review')->where(array('articleid' => $id, 'status' => 1))->count();
|
||
}
|
||
}
|
||
|
||
/****评论回复数*****/
|
||
function getrevie($id)
|
||
{
|
||
return db('cartoon_feedback_review')->where('feed_id', $id)->count();
|
||
}
|
||
/*****阅读进度*******/
|
||
function getyuedu($id, $model = 2)
|
||
{
|
||
if ($model == 2) {
|
||
$volumes = db('cartoon')->where('id', $id)->value('volumes');
|
||
} else {
|
||
$volumes = db('novel')->where('id', $id)->value('chapters');
|
||
}
|
||
$his = db('history')->where(['articleid' => $id, 'model' => $model, 'uid' => session('user_auth.uid')])->order('create_time desc')->limit(1)->find();
|
||
if ($his) {
|
||
return round(($his['order'] / $volumes) * 100, 2) . '%';
|
||
} else {
|
||
return '0%';
|
||
}
|
||
}
|
||
//总浏览 = 点击漫画数量+收藏*10 +一个赞 +打赏
|
||
function getrenqi($bookinfo, $model = 2)
|
||
{
|
||
$renqi = 0;
|
||
if ($model == 2) {
|
||
$s_sc = db('collect')->where('cartoon_id', $bookinfo['id'])->count();
|
||
$s_ds = db('bookbonus')->where(array('articleid' => $bookinfo['id'], 'model' => 2))->sum('actvalue');
|
||
$renqi = $bookinfo['allvisit'] + $s_sc * 10 + $bookinfo['goodnum'] + $s_ds;
|
||
} else {
|
||
//打赏数
|
||
$s_ds = db('bookbonus')->where(array('articleid' => $bookinfo['id'], 'model' => 1))->sum('actvalue');
|
||
$renqi = $bookinfo['allvisit'] + $bookinfo['allcollect'] * 10 + $bookinfo['goodnum'] + $s_ds;
|
||
}
|
||
return $renqi;
|
||
}
|
||
|
||
/*创建目录**/
|
||
function createdir($dirname, $mode = 511, $recursive = false)
|
||
{
|
||
if (!$recursive) {
|
||
$ret = @mkdir($dirname, $mode);
|
||
|
||
if ($ret) {
|
||
@chmod($dirname, $mode);
|
||
}
|
||
|
||
return $ret;
|
||
}
|
||
|
||
if (is_dir($dirname)) {
|
||
return true;
|
||
} else if (createdir(dirname($dirname), $mode, true)) {
|
||
$ret = @mkdir($dirname, $mode);
|
||
|
||
if ($ret) {
|
||
@chmod($dirname, $mode);
|
||
}
|
||
|
||
return $ret;
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
/*****检查目录****/
|
||
function checkdir($dirname, $autocreate = false)
|
||
{
|
||
if (is_dir($dirname)) {
|
||
return true;
|
||
} else if (!$autocreate) {
|
||
return false;
|
||
} else {
|
||
return createdir($dirname, 511, true);
|
||
}
|
||
}
|
||
|
||
/**删除目录***/
|
||
function delfolder($dirname, $flag = true)
|
||
{
|
||
$dirname = trim($dirname);
|
||
$matches = array();
|
||
|
||
|
||
$handle = @opendir($dirname);
|
||
|
||
if ($handle === false) {
|
||
return true;
|
||
}
|
||
|
||
while (($file = @readdir($handle)) !== false) {
|
||
if (($file != '.') && ($file != '..')) {
|
||
if (is_dir($dirname . DIRECTORY_SEPARATOR . $file)) {
|
||
delfolder($dirname . DIRECTORY_SEPARATOR . $file, true);
|
||
} else {
|
||
@unlink($dirname . DIRECTORY_SEPARATOR . $file);
|
||
}
|
||
}
|
||
}
|
||
|
||
@closedir($handle);
|
||
|
||
if ($flag) {
|
||
@rmdir($dirname);
|
||
}
|
||
|
||
return true;
|
||
}
|
||
|
||
/***文件命名***/
|
||
function getRandomName($name = 0)
|
||
{
|
||
if ($name) {
|
||
@$pos = strrpos($name, ".");
|
||
@$fileExt = strtolower(substr($name, $pos));
|
||
}
|
||
ini_set('date.timezone', 'Asia/Shanghai');
|
||
$t = getdate();
|
||
@$year = $t[year];
|
||
@$mon = $t[mon] > 10 ? $t[mon] : "0" . $t[mon];
|
||
@$day = $t[day] > 10 ? $t[day] : "0" . $t[day];
|
||
@$hours = $t[hours] > 10 ? $t[hours] : "0" . $t[hours];
|
||
@$minutes = $t[minutes] > 10 ? $t[minutes] : "0" . $t[minutes];
|
||
@$seconds = $t[seconds] > 10 ? $t[seconds] : "0" . $t[seconds];
|
||
if ($name) {
|
||
return $year . $mon . $day . $hours . $minutes . $seconds . rand(1000, 9999) . $fileExt;
|
||
} else {
|
||
return $year . $mon . $day . $hours . $minutes . $seconds . rand(1000, 9999);
|
||
}
|
||
}
|
||
|
||
|
||
/****获取网络图片并保存******/
|
||
function file_get_img($img, $save_dir, $url = false, $filename = null)
|
||
{
|
||
$cover = @file_get_contents($img);
|
||
if ($cover) {
|
||
if (empty($filename)) {
|
||
$filename = getRandomName($img);
|
||
}
|
||
|
||
if (file_exists(ROOT_PATH . $save_dir) === false) {
|
||
checkdir(ROOT_PATH . $save_dir, 1);
|
||
}
|
||
$fp2 = @fopen(ROOT_PATH . $save_dir . $filename, 'a');
|
||
fwrite($fp2, $cover);
|
||
fclose($fp2);
|
||
unset($cover);
|
||
$path = "/" . $save_dir . $filename;
|
||
if ($url) {
|
||
return $path;
|
||
} else {
|
||
$data['create_time'] = time();
|
||
$data['md5'] = md5_file($img);
|
||
$data['sha1'] = sha1_file($img);
|
||
$data['url'] = $data['path'] = $path;
|
||
$data['status'] = 1;
|
||
$id = db("picture")->insertGetId($data);
|
||
return $id;
|
||
}
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
// 转化作者的收入
|
||
function get_wtiter_income($articleid, $price)
|
||
{
|
||
$book = db('novel')->where(['id' => $articleid])->find();
|
||
//计算方法: (书币*(1-推广成本)*分成比例)/100
|
||
$money = ($price * (1 - ($book['promotionCost'] ? $book['promotionCost'] : config('promotioncost'))) * ($book['profitProportion'] ? $book['profitProportion'] : config('authorincome'))) / 100;
|
||
return $money;
|
||
}
|
||
|
||
/**
|
||
* [将Base64图片转换为本地图片并保存]
|
||
* @param [Base64] $base64_image_content [要保存的Base64]
|
||
* @param [目录] $path [要保存的路径]
|
||
*/
|
||
function base64_image_content($base64_image_content, $path)
|
||
{
|
||
//匹配出图片的格式
|
||
if (preg_match('/^(data:\s*image\/(\w+);base64,)/', $base64_image_content, $result)) {
|
||
$type = $result[2];
|
||
$new_file = $path;
|
||
if (!file_exists($new_file)) {
|
||
//检查是否有该文件夹,如果没有就创建,并给予最高权限
|
||
mkdir($new_file, 0700);
|
||
}
|
||
$new_file = $new_file . getRandomName() . ".{$type}";
|
||
if (file_put_contents($new_file, base64_decode(str_replace($result[1], '', $base64_image_content)))) {
|
||
return '/' . $new_file;
|
||
} else {
|
||
return false;
|
||
}
|
||
} else {
|
||
return false;
|
||
}
|
||
}
|
||
|
||
function genqrcode($data)
|
||
{
|
||
Vendor('phpqrcode.qrlib');
|
||
return QRcode::png($data);
|
||
}
|
||
//Emoji表情将unicode编码转为utf-8编码
|
||
function emoji($emoji_str)
|
||
{
|
||
$emoji_str = '["' . $emoji_str . '"]';
|
||
$emoji_arr = json_decode($emoji_str, true);
|
||
if (count($emoji_arr) == 1) {
|
||
return $emoji_arr[0];
|
||
} else {
|
||
return null;
|
||
}
|
||
}
|
||
|
||
/**
|
||
* get_count_content [统计章节内容字数]
|
||
*
|
||
* @return type
|
||
**/
|
||
function get_count_content($content)
|
||
{
|
||
return round(strlen(preg_replace('/\\s/', '', strip_tags(str_replace(" ", "", $content)))) / 3);
|
||
}
|
||
|
||
|
||
/**
|
||
* get_menuurl [获取渠道、代理商对应的连接]
|
||
*
|
||
* @param type $uid [用户ID]
|
||
* @param type $wxmpid [微信公众号ID]
|
||
* @param type $appId [微信公众号appId]
|
||
*
|
||
* @return type
|
||
**/
|
||
function get_menuurl($uid, $wxmpid = 0, $appId = 0)
|
||
{
|
||
$result = db('member')->find($uid);
|
||
$site_url = config('web_site_url');
|
||
$url = '';
|
||
$wxmp = array();
|
||
//渠道用户
|
||
if ($result['is_top'] == 1) {
|
||
//渠道服务号是否存在
|
||
if ($wxmpid) {
|
||
$wxmp = db('wxmp')->where(['id' => $wxmpid, 'status' => 1])->field('id,open_appid')->find();
|
||
} elseif ($appId) {
|
||
$wxmp = db('wxmp')->where(['uid' => $uid, 'appid' => $appId, 'status' => 1])->field('id,open_appid')->find();
|
||
}
|
||
|
||
if ($wxmp) {
|
||
$url = get_agent_domain($uid, $wxmp['open_appid'], $wxmp['id']);
|
||
} else {
|
||
$url = $site_url;
|
||
}
|
||
} else {
|
||
//代理商对应的渠道用户服务号是否存在
|
||
if ($wxmpid && $result['s_uid'] != 1 && $result['s_uid']) {
|
||
$wxmp = db('wxmp')->where(['id' => $wxmpid, 'status' => 1])->field('id,open_appid')->find();
|
||
}
|
||
if ($wxmp) {
|
||
$url = get_agent_domain($result['s_uid'], $wxmp['open_appid'], $wxmp['id']);
|
||
} else {
|
||
$url = $site_url;
|
||
}
|
||
}
|
||
return $url;
|
||
}
|
||
|
||
/**
|
||
* get_agent_domain [输出渠道用户推广域名]
|
||
*
|
||
* @param type $uid [用户ID]
|
||
* @param type $appid [分销平台appid]
|
||
* @param type $wxmpid [公众号ID]
|
||
*
|
||
* @return type
|
||
**/
|
||
function get_agent_domain($uid, $appid, $wxmpid)
|
||
{
|
||
$open = db('wxopen_account')->where('appid', $appid)->field('id,domain')->find();
|
||
return "http://t" . $uid . "-" . $open['id'] . "-" . $wxmpid . "." . str_replace("www.", "", $open['domain']);
|
||
}
|
||
|
||
//分解域名传递的参数
|
||
function split_host($data, $field = 0)
|
||
{
|
||
$hostdata = explode("-", str_replace("t", "", $data)); //0:uid 1:siteid 2:wxmpid
|
||
return $field ? $hostdata[$field] : $hostdata[0];
|
||
}
|
||
|
||
/****获取微信公众号信息*****/
|
||
function get_wxmp($wxmpid)
|
||
{
|
||
$wxmpid = $wxmpid ? $wxmpid : 1;
|
||
$nickname = db('wxmp')->where('id=' . $wxmpid)->value("nickname");
|
||
return $nickname;
|
||
}
|
||
|
||
//发送TPC请求 $url = IP $data = 数据
|
||
function pushMessageToClient($url, $data)
|
||
{
|
||
//初使化init方法
|
||
$ch = curl_init();
|
||
//指定URL
|
||
curl_setopt($ch, CURLOPT_URL, $url);
|
||
//设定请求后返回结果
|
||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||
//声明使用POST方式来进行发送
|
||
curl_setopt($ch, CURLOPT_POST, 1);
|
||
//发送什么数据呢
|
||
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
|
||
//忽略证书
|
||
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
|
||
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
|
||
//忽略header头信息
|
||
curl_setopt($ch, CURLOPT_HEADER, 0);
|
||
//设置超时时间
|
||
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
|
||
//发送请求
|
||
$output = curl_exec($ch);
|
||
curl_close($ch);
|
||
//返回数据
|
||
return $output;
|
||
}
|
||
/**
|
||
* 发送HTTP请求方法,目前只支持CURL发送请求
|
||
* @param string $url 请求URL
|
||
* @param array $param GET参数数组
|
||
* @param array $data POST的数据,GET请求时该参数无效
|
||
* @param string $method 请求方法GET/POST
|
||
* @return array 响应数据
|
||
*/
|
||
function http($url, $param, $data = '', $method = 'GET')
|
||
{
|
||
$opts = array(
|
||
CURLOPT_TIMEOUT => 30,
|
||
CURLOPT_RETURNTRANSFER => 1,
|
||
CURLOPT_SSL_VERIFYPEER => false,
|
||
CURLOPT_SSL_VERIFYHOST => false,
|
||
);
|
||
|
||
/* 根据请求类型设置特定参数 */
|
||
$opts[CURLOPT_URL] = $url . '?' . http_build_query($param);
|
||
|
||
if (strtoupper($method) == 'POST') {
|
||
$opts[CURLOPT_POST] = 1;
|
||
$opts[CURLOPT_POSTFIELDS] = $data;
|
||
|
||
if (is_string($data)) { //发送JSON数据
|
||
$opts[CURLOPT_HTTPHEADER] = array(
|
||
'Content-Type: application/json; charset=utf-8',
|
||
'Content-Length: ' . strlen($data),
|
||
);
|
||
}
|
||
}
|
||
|
||
/* 初始化并执行curl请求 */
|
||
$ch = curl_init();
|
||
curl_setopt_array($ch, $opts);
|
||
$data = curl_exec($ch);
|
||
$error = curl_error($ch);
|
||
curl_close($ch);
|
||
|
||
//发生错误,抛出异常
|
||
if ($error) throw new \Exception('请求发生错误:' . $error);
|
||
|
||
return $data;
|
||
}
|
||
// 返回去掉域名后的路径
|
||
function parseurl($url)
|
||
{
|
||
$paths = parse_url($url);
|
||
return substr($paths['path'], 1, 100);
|
||
}
|
||
|
||
// 客服消息推送筛选公众号前端使用
|
||
function chackwxid($id, $list)
|
||
{
|
||
$is = false;
|
||
if ($list == 0) {
|
||
return false;
|
||
} else {
|
||
foreach ($list as $k => $v) {
|
||
if ($v == $id) {
|
||
$is = true;
|
||
}
|
||
}
|
||
return $is;
|
||
}
|
||
}
|
||
|
||
function compressedImage($imgsrc, $imgdst, $per = 60)
|
||
{
|
||
list($width, $height, $type) = getimagesize($imgsrc);
|
||
$new_width = $width; //压缩后的图片宽
|
||
$new_height = $height; //压缩后的图片高
|
||
|
||
switch ($type) {
|
||
case 1:
|
||
$giftype = check_gifcartoon($imgsrc);
|
||
if ($giftype) {
|
||
header('Content-Type:image/gif');
|
||
$image_wp = imagecreatetruecolor($new_width, $new_height);
|
||
$image = imagecreatefromgif($imgsrc);
|
||
imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); //90代表的是质量、压缩图片容量大小
|
||
imagejpeg($image_wp, $imgdst, $per);
|
||
imagedestroy($image_wp);
|
||
imagedestroy($image);
|
||
}
|
||
break;
|
||
case 2:
|
||
header('Content-Type:image/jpeg');
|
||
$image_wp = imagecreatetruecolor($new_width, $new_height);
|
||
$image = imagecreatefromjpeg($imgsrc);
|
||
imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); //90代表的是质量、压缩图片容量大小
|
||
imagejpeg($image_wp, $imgdst, $per);
|
||
imagedestroy($image_wp);
|
||
imagedestroy($image);
|
||
break;
|
||
case 3:
|
||
header('Content-Type:image/png');
|
||
$image_wp = imagecreatetruecolor($new_width, $new_height);
|
||
$image = imagecreatefrompng($imgsrc);
|
||
imagecopyresampled($image_wp, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height); //90代表的是质量、压缩图片容量大小
|
||
imagejpeg($image_wp, $imgdst, $per);
|
||
imagedestroy($image_wp);
|
||
imagedestroy($image);
|
||
break;
|
||
}
|
||
}
|
||
|
||
|
||
function check_gifcartoon($image_file)
|
||
{
|
||
$fp = fopen($image_file, 'rb');
|
||
$image_head = fread($fp, 1024);
|
||
fclose($fp);
|
||
return preg_match("/" . chr(0x21) . chr(0xff) . chr(0x0b) . 'NETSCAPE2.0' . "/", $image_head) ? false : true;
|
||
}
|
||
|
||
/*
|
||
* 字符串超过固定长度用省略号表示
|
||
*/
|
||
function sub_title($text, $length = 8, $replace = '...', $encoding = 'UTF-8')
|
||
{
|
||
if ($text && mb_strlen($text, $encoding) > $length) {
|
||
return mb_substr($text, 0, $length, $encoding) . $replace;
|
||
}
|
||
return $text;
|
||
}
|
||
/**
|
||
* 所有cp方
|
||
* @return string
|
||
*/
|
||
function cp()
|
||
{
|
||
$config = Config::get('ytdb'); //读取第二个数据库配置
|
||
$ytdb = Db::connect($config); //连接数据库
|
||
return $ytdb->name('cps')->field('id,name')->where('id', '>', 1)->select();
|
||
}
|
||
|
||
//根据用户adid匹配对应计划名称
|
||
function usermatchaidname($ldurl, $adid)
|
||
{
|
||
$w['ldurl'] = $ldurl;
|
||
$w['aidname'] = array('neq', '');
|
||
$w['adid'] = $adid;
|
||
$name = db('member')->where($w)->order('uid desc')->value('aidname');
|
||
return $name;
|
||
}
|
||
|
||
//截取patthinfo url参数
|
||
function convertUrlQuery($query)
|
||
{
|
||
$queryParts = explode('/', $query);
|
||
$params = array();
|
||
foreach ($queryParts as $k => $v) {
|
||
$params[$v] = $queryParts[$k + 1];
|
||
}
|
||
return $params;
|
||
}
|
||
|
||
|
||
/**
|
||
* 获取DecodeToken数据
|
||
*
|
||
* @author dotdotdot <6383846@qq.com>
|
||
* @date 2022-08-12
|
||
*/
|
||
function getDecodeTokenData()
|
||
{
|
||
$header = Request::instance()->header();
|
||
|
||
$token = $header['token'];
|
||
|
||
$decode = JWT::decode($token, new Key(config('jwt.key'), config('jwt.sign_type')));
|
||
|
||
return (array)$decode->data;
|
||
}
|
||
|
||
/**
|
||
* 重组数组元素
|
||
*
|
||
* @author dotdotdot <6383846@qq.com>
|
||
* @date 2022-08-15
|
||
* @param array $rawData 原始数据
|
||
* @param string $indexKey 返回索引
|
||
* @param array $containsValue 返回包含的值
|
||
*/
|
||
function array_columns(array $rawData, string $indexKey, array $containsValue)
|
||
{
|
||
$tmpData = [];
|
||
foreach ($containsValue as $containsValue) {
|
||
foreach ($rawData as $rawValue) {
|
||
if (array_key_exists($containsValue, $rawValue)) {
|
||
$tmpData[$rawValue[$indexKey]][$containsValue] = $rawValue[$containsValue];
|
||
}
|
||
}
|
||
}
|
||
|
||
return $tmpData;
|
||
}
|