= 1024 && $i < 5; $i++) { $size /= 1024; } return round($size, $precision) . $delimiter . $units[$i]; } } if (!function_exists('datetime')) { /** * 将时间戳转换为日期时间 * @param int $time 时间戳 * @param string $format 日期时间格式 * @return string */ function datetime($time, $format = 'Y-m-d H:i:s') { $time = is_numeric($time) ? $time : strtotime($time); return date($format, $time); } } if (!function_exists('human_date')) { /** * 获取语义化时间 * @param int $time 时间 * @param int $local 本地时间 * @return string */ function human_date($time, $local = null) { return \fast\Date::human($time, $local); } } if (!function_exists('cdnurl')) { /** * 获取上传资源的CDN的地址 * @param string $url 资源相对地址 * @param boolean $domain 是否显示域名 或者直接传入域名 * @return string */ function cdnurl($url, $domain = false) { $regex = "/^((?:[a-z]+:)?\/\/|data:image\/)(.*)/i"; $cdnurl = \think\Config::get('upload.cdnurl'); if (is_bool($domain) || stripos($cdnurl, '/') === 0) { $url = preg_match($regex, $url) || ($cdnurl && stripos($url, $cdnurl) === 0) ? $url : $cdnurl . $url; } if ($domain && !preg_match($regex, $url)) { $domain = is_bool($domain) ? request()->domain() : $domain; $url = $domain . $url; } return $url; } } if (!function_exists('is_really_writable')) { /** * 判断文件或文件夹是否可写 * @param string $file 文件或目录 * @return bool */ function is_really_writable($file) { if (DIRECTORY_SEPARATOR === '/') { return is_writable($file); } if (is_dir($file)) { $file = rtrim($file, '/') . '/' . md5(mt_rand()); if (($fp = @fopen($file, 'ab')) === false) { return false; } fclose($fp); @chmod($file, 0777); @unlink($file); return true; } elseif (!is_file($file) or ($fp = @fopen($file, 'ab')) === false) { return false; } fclose($fp); return true; } } if (!function_exists('rmdirs')) { /** * 删除文件夹 * @param string $dirname 目录 * @param bool $withself 是否删除自身 * @return boolean */ function rmdirs($dirname, $withself = true) { if (!is_dir($dirname)) { return false; } $files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($dirname, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::CHILD_FIRST ); foreach ($files as $fileinfo) { $todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink'); $todo($fileinfo->getRealPath()); } if ($withself) { @rmdir($dirname); } return true; } } if (!function_exists('copydirs')) { /** * 复制文件夹 * @param string $source 源文件夹 * @param string $dest 目标文件夹 */ function copydirs($source, $dest) { if (!is_dir($dest)) { mkdir($dest, 0755, true); } foreach ( $iterator = new RecursiveIteratorIterator( new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS), RecursiveIteratorIterator::SELF_FIRST ) as $item ) { if ($item->isDir()) { $sontDir = $dest . DS . $iterator->getSubPathName(); if (!is_dir($sontDir)) { mkdir($sontDir, 0755, true); } } else { copy($item, $dest . DS . $iterator->getSubPathName()); } } } } if (!function_exists('mb_ucfirst')) { function mb_ucfirst($string) { return mb_strtoupper(mb_substr($string, 0, 1)) . mb_strtolower(mb_substr($string, 1)); } } if (!function_exists('addtion')) { /** * 附加关联字段数据 * @param array $items 数据列表 * @param mixed $fields 渲染的来源字段 * @return array */ function addtion($items, $fields) { if (!$items || !$fields) { return $items; } $fieldsArr = []; if (!is_array($fields)) { $arr = explode(',', $fields); foreach ($arr as $k => $v) { $fieldsArr[$v] = ['field' => $v]; } } else { foreach ($fields as $k => $v) { if (is_array($v)) { $v['field'] = $v['field'] ?? $k; } else { $v = ['field' => $v]; } $fieldsArr[$v['field']] = $v; } } foreach ($fieldsArr as $k => &$v) { $v = is_array($v) ? $v : ['field' => $v]; $v['display'] = $v['display'] ?? str_replace(['_ids', '_id'], ['_names', '_name'], $v['field']); $v['primary'] = $v['primary'] ?? ''; $v['column'] = $v['column'] ?? 'name'; $v['model'] = $v['model'] ?? ''; $v['table'] = $v['table'] ?? ''; $v['name'] = $v['name'] ?? str_replace(['_ids', '_id'], '', $v['field']); } unset($v); $ids = []; $fields = array_keys($fieldsArr); foreach ($items as $k => $v) { foreach ($fields as $m => $n) { if (isset($v[$n])) { $ids[$n] = array_merge(isset($ids[$n]) && is_array($ids[$n]) ? $ids[$n] : [], explode(',', $v[$n])); } } } $result = []; foreach ($fieldsArr as $k => $v) { if ($v['model']) { $model = new $v['model']; } else { // 优先判断使用table的配置 $model = $v['table'] ? \think\Db::table($v['table']) : \think\Db::name($v['name']); } $primary = $v['primary'] ?: $model->getPk(); $result[$v['field']] = isset($ids[$v['field']]) ? $model->where($primary, 'in', $ids[$v['field']])->column($v['column'], $primary) : []; } foreach ($items as $k => &$v) { foreach ($fields as $m => $n) { if (isset($v[$n])) { $curr = array_flip(explode(',', $v[$n])); $linedata = array_intersect_key($result[$n], $curr); $v[$fieldsArr[$n]['display']] = $fieldsArr[$n]['column'] == '*' ? $linedata : implode(',', $linedata); } } } return $items; } } if (!function_exists('var_export_short')) { /** * 使用短标签打印或返回数组结构 * @param mixed $data * @param boolean $return 是否返回数据 * @return string */ function var_export_short($data, $return = true) { return var_export($data, $return); } } if (!function_exists('letter_avatar')) { /** * 首字母头像 * @param $text * @return string */ function letter_avatar($text) { $total = unpack('L', hash('adler32', $text, true))[1]; $hue = $total % 360; list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9); $bg = "rgb({$r},{$g},{$b})"; $color = "#ffffff"; $first = mb_strtoupper(mb_substr($text, 0, 1)); $src = base64_encode('' . $first . ''); $value = 'data:image/svg+xml;base64,' . $src; return $value; } } if (!function_exists('hsv2rgb')) { function hsv2rgb($h, $s, $v) { $r = $g = $b = 0; $i = floor($h * 6); $f = $h * 6 - $i; $p = $v * (1 - $s); $q = $v * (1 - $f * $s); $t = $v * (1 - (1 - $f) * $s); switch ($i % 6) { case 0: $r = $v; $g = $t; $b = $p; break; case 1: $r = $q; $g = $v; $b = $p; break; case 2: $r = $p; $g = $v; $b = $t; break; case 3: $r = $p; $g = $q; $b = $v; break; case 4: $r = $t; $g = $p; $b = $v; break; case 5: $r = $v; $g = $p; $b = $q; break; } return [ floor($r * 255), floor($g * 255), floor($b * 255) ]; } } if (!function_exists('check_nav_active')) { /** * 检测会员中心导航是否高亮 */ function check_nav_active($url, $classname = 'active') { $auth = \app\common\library\Auth::instance(); $requestUrl = $auth->getRequestUri(); $url = ltrim($url, '/'); return $requestUrl === str_replace(".", "/", $url) ? $classname : ''; } } if (!function_exists('check_cors_request')) { /** * 跨域检测 */ function check_cors_request() { if (isset($_SERVER['HTTP_ORIGIN']) && $_SERVER['HTTP_ORIGIN'] && config('fastadmin.cors_request_domain')) { $info = parse_url($_SERVER['HTTP_ORIGIN']); $domainArr = explode(',', config('fastadmin.cors_request_domain')); $domainArr[] = request()->host(true); if (in_array("*", $domainArr) || in_array($_SERVER['HTTP_ORIGIN'], $domainArr) || (isset($info['host']) && in_array($info['host'], $domainArr))) { header("Access-Control-Allow-Origin: " . $_SERVER['HTTP_ORIGIN']); } else { $response = Response::create('跨域检测无效', 'html', 403); throw new HttpResponseException($response); } header('Access-Control-Allow-Credentials: true'); header('Access-Control-Max-Age: 86400'); if ($_SERVER['REQUEST_METHOD'] == 'OPTIONS') { if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) { header("Access-Control-Allow-Methods: GET, POST, PUT, DELETE, OPTIONS"); } if (isset($_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS'])) { header("Access-Control-Allow-Headers: {$_SERVER['HTTP_ACCESS_CONTROL_REQUEST_HEADERS']}"); } $response = Response::create('', 'html'); throw new HttpResponseException($response); } } } } if (!function_exists('xss_clean')) { /** * 清理XSS */ function xss_clean($content, $is_image = false) { return \app\common\library\Security::instance()->xss_clean($content, $is_image); } } if (!function_exists('url_clean')) { /** * 清理URL */ function url_clean($url) { if (!check_url_allowed($url)) { return ''; } return xss_clean($url); } } if (!function_exists('check_ip_allowed')) { /** * 检测IP是否允许 * @param string $ip IP地址 */ function check_ip_allowed($ip = null) { $ip = is_null($ip) ? request()->ip() : $ip; $forbiddenipArr = config('site.forbiddenip'); $forbiddenipArr = !$forbiddenipArr ? [] : $forbiddenipArr; $forbiddenipArr = is_array($forbiddenipArr) ? $forbiddenipArr : array_filter(explode("\n", str_replace("\r\n", "\n", $forbiddenipArr))); if ($forbiddenipArr && \Symfony\Component\HttpFoundation\IpUtils::checkIp($ip, $forbiddenipArr)) { $response = Response::create('请求无权访问', 'html', 403); throw new HttpResponseException($response); } } } if (!function_exists('check_url_allowed')) { /** * 检测URL是否允许 * @param string $url URL * @return bool */ function check_url_allowed($url = '') { //允许的主机列表 $allowedHostArr = [ strtolower(request()->host()) ]; if (empty($url)) { return true; } //如果是站内相对链接则允许 if (preg_match("/^[\/a-z][a-z0-9][a-z0-9\.\/]+((\?|#).*)?\$/i", $url) && substr($url, 0, 2) !== '//') { return true; } //如果是站外链接则需要判断HOST是否允许 if (preg_match("/((http[s]?:\/\/)+((?>[a-z\-0-9]{2,}\.)+[a-z]{2,8}|((?>([0-9]{1,3}\.)){3}[0-9]{1,3}))(:[0-9]{1,5})?)(?:\s|\/)/i", $url)) { $chkHost = parse_url(strtolower($url), PHP_URL_HOST); if ($chkHost && in_array($chkHost, $allowedHostArr)) { return true; } } return false; } } if (!function_exists('build_suffix_image')) { /** * 生成文件后缀图片 * @param string $suffix 后缀 * @param null $background * @return string */ function build_suffix_image($suffix, $background = null) { $suffix = mb_substr(strtoupper($suffix), 0, 4); $total = unpack('L', hash('adler32', $suffix, true))[1]; $hue = $total % 360; list($r, $g, $b) = hsv2rgb($hue / 360, 0.3, 0.9); $background = $background ? $background : "rgb({$r},{$g},{$b})"; $icon = << {$suffix} EOT; return $icon; } } //本地地址转换为网络地址 function localpath_to_netpath($path) { $config = get_system_config(); if (empty($path)) { return ''; } elseif (strrpos($path, 'http') !== false) { return $path; } else { $static_resource_url = ''; if ($config['file_upload_type'] == 1) { $static_resource_url = $config['loacl_resource_url']; }elseif ($config['file_upload_type'] == 2) { $static_resource_url = $config['oss_cdn_url']; }else{ $static_resource_url = ""; } $path = str_replace("\\", "/", $path); $path = $static_resource_url . $path; } return $path; } /** * @param int $type 1生成昵称,2生成姓名 * @param int $nameLong 如果type=2时传此字段 除去姓, 名的长度 如姓名时两个字就传1 姓名时三个字就传2 * //汉语 - 给用户自动生成昵称 */ function random_nickname($type = 1,$nameLong=2){ // 随机昵称 形容词 $nicheng_tou=['迷你的','鲜艳的','飞快的','真实的','清新的','幸福的','可耐的','快乐的','冷静的','醉熏的','潇洒的','糊涂的','积极的','冷酷的','深情的','粗暴的', '温柔的','可爱的','愉快的','义气的','认真的','威武的','帅气的','传统的','潇洒的','漂亮的','自然的','专一的','听话的','昏睡的','狂野的','等待的','搞怪的', '幽默的','魁梧的','活泼的','开心的','高兴的','超帅的','留胡子的','坦率的','直率的','轻松的','痴情的','完美的','精明的','无聊的','有魅力的','丰富的','繁荣的', '饱满的','炙热的','暴躁的','碧蓝的','俊逸的','英勇的','健忘的','故意的','无心的','土豪的','朴实的','兴奋的','幸福的','淡定的','不安的','阔达的','孤独的', '独特的','疯狂的','时尚的','落后的','风趣的','忧伤的','大胆的','爱笑的','矮小的','健康的','合适的','玩命的','沉默的','斯文的','香蕉','苹果','鲤鱼','鳗鱼', '任性的','细心的','粗心的','大意的','甜甜的','酷酷的','健壮的','英俊的','霸气的','阳光的','默默的','大力的','孝顺的','忧虑的','着急的','紧张的','善良的', '凶狠的','害怕的','重要的','危机的','欢喜的','欣慰的','满意的','跳跃的','诚心的','称心的','如意的','怡然的','娇气的','无奈的','无语的','激动的','愤怒的', '美好的','感动的','激情的','激昂的','震动的','虚拟的','超级的','寒冷的','精明的','明理的','犹豫的','忧郁的','寂寞的','奋斗的','勤奋的','现代的','过时的', '稳重的','热情的','含蓄的','开放的','无辜的','多情的','纯真的','拉长的','热心的','从容的','体贴的','风中的','曾经的','追寻的','儒雅的','优雅的','开朗的', '外向的','内向的','清爽的','文艺的','长情的','平常的','单身的','伶俐的','高大的','懦弱的','柔弱的','爱笑的','乐观的','耍酷的','酷炫的','神勇的','年轻的', '唠叨的','瘦瘦的','无情的','包容的','顺心的','畅快的','舒适的','靓丽的','负责的','背后的','简单的','谦让的','彩色的','缥缈的','欢呼的','生动的','复杂的', '慈祥的','仁爱的','魔幻的','虚幻的','淡然的','受伤的','雪白的','高高的','糟糕的','顺利的','闪闪的','羞涩的','缓慢的','迅速的','优秀的','聪明的','含糊的', '俏皮的','淡淡的','坚强的','平淡的','欣喜的','能干的','灵巧的','友好的','机智的','机灵的','正直的','谨慎的','俭朴的','殷勤的','虚心的','辛勤的','自觉的', '无私的','无限的','踏实的','老实的','现实的','可靠的','务实的','拼搏的','个性的','粗犷的','活力的','成就的','勤劳的','单纯的','落寞的','朴素的','悲凉的', '忧心的','洁净的','清秀的','自由的','小巧的','单薄的','贪玩的','刻苦的','干净的','壮观的','和谐的','文静的','调皮的','害羞的','安详的','自信的','端庄的', '坚定的','美满的','舒心的','温暖的','专注的','勤恳的','美丽的','腼腆的','优美的','甜美的','甜蜜的','整齐的','动人的','典雅的','尊敬的','舒服的','妩媚的', '秀丽的','喜悦的','甜美的','彪壮的','强健的','大方的','俊秀的','聪慧的','迷人的','陶醉的','悦耳的','动听的','明亮的','结实的','魁梧的','标致的','清脆的', '敏感的','光亮的','大气的','老迟到的','知性的','冷傲的','呆萌的','野性的','隐形的','笑点低的','微笑的','笨笨的','难过的','沉静的','火星上的','失眠的', '安静的','纯情的','要减肥的','迷路的','烂漫的','哭泣的','贤惠的','苗条的','温婉的','发嗲的','会撒娇的','贪玩的','执着的','眯眯眼的','花痴的','想人陪的', '眼睛大的','高贵的','傲娇的','心灵美的','爱撒娇的','细腻的','天真的','怕黑的','感性的','飘逸的','怕孤独的','忐忑的','高挑的','傻傻的','冷艳的','爱听歌的', '还单身的','怕孤单的','懵懂的']; // 随机昵称 名词 $nicheng_wei=['嚓茶','皮皮虾','皮卡丘','马里奥','小霸王','凉面','便当','毛豆','花生','可乐','灯泡','哈密瓜','野狼','背包','眼神','缘分','雪碧','人生','牛排', '蚂蚁','飞鸟','灰狼','斑马','汉堡','悟空','巨人','绿茶','自行车','保温杯','大碗','墨镜','魔镜','煎饼','月饼','月亮','星星','芝麻','啤酒','玫瑰', '大叔','小伙','哈密瓜,数据线','太阳','树叶','芹菜','黄蜂','蜜粉','蜜蜂','信封','西装','外套','裙子','大象','猫咪','不知道','路灯','蓝天','白云', '星月','彩虹','微笑','摩托','板栗','高山','大地','大树','电灯胆','砖头','楼房','水池','鸡翅','蜻蜓','红牛','咖啡','机器猫','枕头','大船','诺言', '钢笔','刺猬','天空','飞机','大炮','冬天','洋葱','春天','夏天','秋天','冬日','航空','毛衣','豌豆','黑米','玉米','眼睛','老鼠','白羊','帅哥','美女', '季节','鲜花','服饰','裙子','白开水','秀发','大山','火车','汽车','歌曲','舞蹈','老师','导师','方盒','大米','麦片','水杯','水壶','手套','鞋子','自行车', '鼠标','手机','电脑','书本','奇迹','身影','香烟','夕阳','台灯','宝贝','未来','皮带','钥匙','心锁','故事','花瓣','滑板','画笔','画板','学姐','店员', '电源','饼干','宝马','过客','大白','时光','石头','钻石','河马','犀牛','西牛','绿草','抽屉','柜子','往事','寒风','路人','橘子','耳机','鸵鸟','朋友', '苗条','铅笔','钢笔','硬币','热狗','大侠','御姐','萝莉','毛巾','期待','盼望','白昼','黑夜','大门','黑裤','钢铁侠','哑铃','板凳','枫叶','荷花','乌龟', '仙人掌','衬衫','大神','草丛','早晨','心情','茉莉','流沙','蜗牛','战斗机','冥王星','猎豹','棒球','篮球','乐曲','电话','网络','世界','中心','鱼','鸡','旺仔', '老虎','鸭子','雨','羽毛','翅膀','外套','火','丝袜','书包','钢笔','冷风','八宝粥','烤鸡','大雁','音响','招牌','胡萝卜','冰棍','帽子','菠萝','蛋挞','香水', '泥猴桃','吐司','溪流','黄豆','樱桃','小鸽子','小蝴蝶','爆米花','花卷','小鸭子','小海豚','日记本','小熊猫','小懒猪','小懒虫','荔枝','镜子','曲奇','金针菇', '小松鼠','小虾米','酒窝','紫菜','金鱼','柚子','果汁','百褶裙','项链','帆布鞋','火龙果','奇异果','煎蛋','唇彩','小土豆','高跟鞋','戒指','雪糕','睫毛','铃铛', '手链','香氛','红酒','月光','酸奶','银耳汤','咖啡豆','小蜜蜂','小蚂蚁','蜡烛','棉花糖','向日葵','水蜜桃','小蝴蝶','小刺猬','小丸子','指甲油','康乃馨','糖豆', '薯片','口红','超短裙','乌冬面','冰淇淋','棒棒糖','长颈鹿','豆芽','发箍','发卡','发夹','发带','铃铛','小馒头','小笼包','小甜瓜','冬瓜','香菇','小兔子', '含羞草','短靴','睫毛膏','小蘑菇','跳跳糖','小白菜','草莓','柠檬','月饼','百合','纸鹤','小天鹅','云朵','芒果','面包','海燕','小猫咪','龙猫','唇膏','鞋垫', '羊','黑猫','白猫','万宝路','金毛','山水','音响','纸飞机','烧鹅']; // 百家姓 $arrXing=['赵','钱','孙','李','周','吴','郑','王','冯','陈','褚','卫','蒋','沈','韩','杨','朱','秦','尤','许','何','吕','施','张','孔','曹','严','华','金','魏','陶','姜','戚','谢','邹', '喻','柏','水','窦','章','云','苏','潘','葛','奚','范','彭','郎','鲁','韦','昌','马','苗','凤','花','方','任','袁','柳','鲍','史','唐','费','薛','雷','贺','倪','汤','滕','殷','罗', '毕','郝','安','常','傅','卞','齐','元','顾','孟','平','黄','穆','萧','尹','姚','邵','湛','汪','祁','毛','狄','米','伏','成','戴','谈','宋','茅','庞','熊','纪','舒','屈','项','祝', '董','梁','杜','阮','蓝','闵','季','贾','路','娄','江','童','颜','郭','梅','盛','林','钟','徐','邱','骆','高','夏','蔡','田','樊','胡','凌','霍','虞','万','支','柯','管','卢','莫', '柯','房','裘','缪','解','应','宗','丁','宣','邓','单','杭','洪','包','诸','左','石','崔','吉','龚','程','嵇','邢','裴','陆','荣','翁','荀','于','惠','甄','曲','封','储','仲','伊', '宁','仇','甘','武','符','刘','景','詹','龙','叶','幸','司','黎','溥','印','怀','蒲','邰','从','索','赖','卓','屠','池','乔','胥','闻','莘','党','翟','谭','贡','劳','逄','姬','申', '扶','堵','冉','宰','雍','桑','寿','通','燕','浦','尚','农','温','别','庄','晏','柴','瞿','阎','连','习','容','向','古','易','廖','庾','终','步','都','耿','满','弘','匡','国','文', '寇','广','禄','阙','东','欧','利','师','巩','聂','关','荆','司马','上官','欧阳','夏侯','诸葛','闻人','东方','赫连','皇甫','尉迟','公羊','澹台','公冶','宗政','濮阳','淳于','单于','太叔', '申屠','公孙','仲孙','轩辕','令狐','徐离','宇文','长孙','慕容','司徒','司空','皮']; //名字 $arrMing=['伟','刚','勇','毅','俊','峰','强','军','平','保','东','文','辉','力','明','永','健','世','广','志','义','兴','良','海','山','仁','波','宁','贵','福','生','龙','元','全' ,'国','胜','学','祥','才','发','武','新','利','清','飞','彬','富','顺','信','子','杰','涛','昌','成','康','星','光','天','达','安','岩','中','茂','进','林','有','坚','和','彪','博','诚' ,'先','敬','震','振','壮','会','思','群','豪','心','邦','承','乐','绍','功','松','善','厚','庆','磊','民','友','裕','河','哲','江','超','浩','亮','政','谦','亨','奇','固','之','轮','翰' ,'朗','伯','宏','言','若','鸣','朋','斌','梁','栋','维','启','克','伦','翔','旭','鹏','泽','晨','辰','士','以','建','家','致','树','炎','德','行','时','泰','盛','雄','琛','钧','冠','策' ,'腾','楠','榕','风','航','弘','秀','娟','英','华','慧','巧','美','娜','静','淑','惠','珠','翠','雅','芝','玉','萍','红','娥','玲','芬','芳','燕','彩','春','菊','兰','凤','洁','梅','琳' ,'素','云','莲','真','环','雪','荣','爱','妹','霞','香','月','莺','媛','艳','瑞','凡','佳','嘉','琼','勤','珍','贞','莉','桂','娣','叶','璧','璐','娅','琦','晶','妍','茜','秋','珊','莎' ,'锦','黛','青','倩','婷','姣','婉','娴','瑾','颖','露','瑶','怡','婵','雁','蓓','纨','仪','荷','丹','蓉','眉','君','琴','蕊','薇','菁','梦','岚','苑','婕','馨','瑗','琰','韵','融','园' ,'艺','咏','卿','聪','澜','纯','毓','悦','昭','冰','爽','琬','茗','羽','希','欣','飘','育','滢','馥','筠','柔','竹','霭','凝','晓','欢','霄','枫','芸','菲','寒','伊','亚','宜','可','姬' ,'舒','影','荔','枝','丽','阳','妮','宝','贝','初','程','梵','罡','恒','鸿','桦','骅','剑','娇','纪','宽','苛','灵','玛','媚','琪','晴','容','睿','烁','堂','唯','威','韦','雯','苇','萱' ,'阅','彦','宇','雨','洋','忠','宗','曼','紫','逸','贤','蝶','菡','绿','蓝','儿','翠','烟']; switch ($type){ case 1: $tou_num=rand(0,count($nicheng_tou)-1); $wei_num=rand(0,count($nicheng_wei)-1); $nicheng=$nicheng_tou[$tou_num].$nicheng_wei[$wei_num]; break; case 2: $nicheng=$arrXing[mt_rand(0,count($arrXing)-1)]; for($i=1;$i<=$nameLong;$i++) { $nicheng .=(mt_rand(0,1)?$arrMing[mt_rand(0,count($arrMing)-1)]:$arrMing[mt_rand(0,count($arrMing)-1)]); } break; } return $nicheng; } //昵称过滤 function nickname_filter($username) { // 定义敏感词数组(包含常见变体) $sensitiveWords = [ // 核心敏感词 '系统管理员', '管理员', '系统管理', '系统', '管理','官方', // 繁体中文 '系統管理員', '管理員', '系統管理', '系統', // 拼音(全拼/简拼) 'xitongguanliyuan', 'guanliyuan', 'xitongguanli', 'xitong', 'guanli', 'xtgly', 'gly', 'xtgl', 'xt', 'gl', // 形近字/同音字替换 '係統', '係管', '管琯', '管里', '珯理', '琯理', '俬统', '俬统', '系捅', '系桶', '管狸', '管锂', '管裡', '管裡', '管悝', // 拆字/间隔形式(带0-2个随机字符) '系[^\\w]{0,2}统', '管[^\\w]{0,2}理', '系[^\\w]{0,2}统[^\\w]{0,2}管', '管[^\\w]{0,2}理[^\\w]{0,2}员', '系[^\\w]{0,2}管', // 火星文变体 '繫統', '筦理', '係統', '係統', '管悡', '管禮', '管裡', // 部首拆分 '糸工', '亻王', '丿𠂉', '𠂉里' ]; // 检查用户名是否包含敏感词 foreach ($sensitiveWords as $word) { // 使用正则表达式匹配(不区分大小写) $pattern = '/' . preg_quote($word, '/') . '/iu'; if (preg_match($pattern, $username)) { return false; // 发现敏感词,返回false } // 检查拆字形式(如"系 统") $spacedPattern = '/' . implode('[\\s\\W]*', preg_split('//u', $word, -1, PREG_SPLIT_NO_EMPTY)) . '/iu'; if (preg_match($spacedPattern, $username)) { return false; } } return true; // 通过检查 } /** * 手机中间四位处理为* * @param string $mobile手机号码 * @return String */ function mobile_format($mobile) { if (!$mobile) { return null; } $pattern = '/(\d{3})(\d{4})(\d{4})/i'; $replacement = '$1****$3'; $mobile = preg_replace($pattern, $replacement, $mobile); return $mobile; } //姓名处理第二位处理为* function name_format($name) { if (!$name) { return null; } $length = mb_strlen( $name, 'UTF-8'); switch( $length) { case 3: return mb_substr( $name, 0, 1, 'UTF-8') . '*' . mb_substr( $name, 2, 2, 'UTF-8'); case 2: return mb_substr( $name, 0, 1, 'UTF-8') . '*'; default: return $name; } } //身份证号除前2 后2位 中间全部显示为* function id_format($idCard) { if (!$idCard) { return null; } $length = strlen( $idCard); // 只处理长度超过4位的情况 if ( $length > 4) { return substr( $idCard, 0, 2) . str_repeat('*', $length - 4) . substr( $idCard, -2); } // 短号码直接返回原值 return $idCard; } /* 检验手机号 */ function checkMobile($mobile){ $ismobile = preg_match("/^1[3|4|5|6|7|8|9]\d{9}$/",$mobile); if($ismobile){ return 1; }else{ return 0; } } /** * 友好的时间显示 */ function time_to_units($time) { //时间判断 是否是时间戳 if (is_numeric($time)) { $time = (int) $time; } else { $time = strtotime($time); } $now_time = time(); $time_diff = $now_time - $time; $tips = ''; $units = [ '31536000' => '年前', '2592000' => '月前', '86400' => '天前', '3600' => '小时前', '60' => '分钟前', '1' => '秒前', ]; foreach ($units as $key => $value) { if ($time_diff > $key) { $num = (int) ($time_diff / $key); $tips = $num . $value; break; } } return $tips; } function get_system_config(){ // 获取系统配置 $config = db('vs_config')->where('is_delete', 1)->column('key_value', 'key_title'); return $config; } function get_system_config_value($key_title){ // 获取系统配置 $config = db('vs_config')->where('is_delete', 1)->where('key_title',$key_title)->value('key_value'); return $config; } //根据类型获取配置 function get_system_config_type($type){ // 获取系统配置 $config = db('vs_config')->where('is_delete', 1)->where('type',$type)->select(); return $config; } //给APP数据整合返回 function V($code, $msg = "", $data = "", $api_version = '') { if(!$data){ $data = null; } header("content:application/json;chartset=uft-8"); $return = ['code' => $code, 'msg' => __($msg), 'data' => $data, 'api_version' => $api_version]; echo json_encode($return); exit(); } //redis锁 function redis_lock_exit($key, $value = 1, $time = 5) { $redis = \think\Cache::store('redis')->handler(); $is_lock = $redis->setnx($key, $value); if (!$is_lock) { return V(0, '您的手速太快了!'); } else { $redis->setex($key, $time, $value); return true; } } //解锁 function redis_unlock($key) { $redis = \think\Cache::store('redis')->handler(); $redis->del($key); return true; } //redis锁 s function redis_lock_exits($key, $value = 1, $time = 5) { // 尝试加锁(设置一个带过期时间的 key,仅当 key 不存在时才设置成功) $is_lock = Cache::has($key); if ($is_lock) { return V(0, '您的手速太快了!'); } else { Cache::set($key, $value, $time); return true; } } //解锁 function redis_unlocks($key) { Cache::rm($key); return true; } function myCurl($url, $post_data = array(), $header = array(), $cookie = "") { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_HEADER, false); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //如果把这行注释掉的话,就会直接输出 $curl_header = array(); if (!empty($header)) { foreach ($header as $k => $v) { $curl_header[] = "$k:$v"; } curl_setopt($ch, CURLOPT_HTTPHEADER, $curl_header); } if (!empty($post_data)) { curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post_data)); } if (!empty($cookie)) { curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie); } curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); $result = curl_exec($ch); curl_close($ch); return $result; } //生成随机数 function generateRandom($num = 0) { $code = strtolower('ABCDEFGHIJKLMNOPQRSTUVWXYZ123456789'); $str = ''; for ($i = 0; $i < $num; $i++) { $str .= $code[mt_rand(0, strlen($code) - 1)]; } return $str; } function generateRandoms($length = 4) { $min = pow(10, $length - 1); $max = pow(10, $length) - 1; return mt_rand($min, $max); } //根据生日获取年龄 function getAge($birthday) { $birthday = strtotime($birthday); $age = date('Y') - date('Y',$birthday); return $age; } //获取星座 function get_user_constellation($birthday) { //判断日期格式是时间戳还是Y-m-d格式 if (is_numeric($birthday)) { $birthday = date('Y-m-d', $birthday); } $birthday_arr = explode('-', $birthday); $month = $birthday_arr[1]; $day = $birthday_arr[2]; $xingzuo = ''; // 检查参数有效性 if ($month < 1 || $month > 12 || $day < 1 || $day > 31) { return $xingzuo; } if (($month == 1 && $day >= 20) || ($month == 2 && $day <= 18)) { $xingzuo = "水瓶座"; } else if (($month == 2 && $day >= 19) || ($month == 3 && $day <= 20)) { $xingzuo = "双鱼座"; } else if (($month == 3 && $day >= 21) || ($month == 4 && $day <= 19)) { $xingzuo = "白羊座"; } else if (($month == 4 && $day >= 20) || ($month == 5 && $day <= 20)) { $xingzuo = "金牛座"; } else if (($month == 5 && $day >= 21) || ($month == 6 && $day <= 21)) { $xingzuo = "双子座"; } else if (($month == 6 && $day >= 22) || ($month == 7 && $day <= 22)) { $xingzuo = "巨蟹座"; } else if (($month == 7 && $day >= 23) || ($month == 8 && $day <= 22)) { $xingzuo = "狮子座"; } else if (($month == 8 && $day >= 23) || ($month == 9 && $day <= 22)) { $xingzuo = "处女座"; } else if (($month == 9 && $day >= 23) || ($month == 10 && $day <= 23)) { $xingzuo = "天秤座"; } else if (($month == 10 && $day >= 24) || ($month == 11 && $day <= 22)) { $xingzuo = "天蝎座"; } else if (($month == 11 && $day >= 23) || ($month == 12 && $day <= 21)) { $xingzuo = "射手座"; } else if (($month == 12 && $day >= 22) || ($month == 1 && $day <= 19)) { $xingzuo = "摩羯座"; } return $xingzuo; } //数字格式话 //function numberFormat($number) { // $num = round($number / 10000, 2); // if ($num > 1) { // $number = $num . 'w'; // } // return $number; //} /** * 数字格式化方法 * @param int|float $number 需要格式化的数字 * @param string $format 格式类型: 'short'(默认简写), 'thousand'(千分位), 'custom'(自定义) * @param int $decimals 小数位数 * @param array $options 其他选项 * @return string 格式化后的数字字符串 */ function numberFormat($number, $format = 'short', $decimals = 2, $options = []) { // 确保输入是数字 if (!is_numeric($number)) { return '0'; } switch ($format) { case 'short': return formatShortNumber($number, $decimals); case 'thousand': return formatThousandNumber($number, $decimals); case 'custom': return formatCustomNumber($number, $options); default: return formatShortNumber($number, $decimals); } } /** * 简写格式化数字 (如: 1.23w, 2.56亿) */ function formatShortNumber($number, $decimals = 2) { $units = ['', 'w', '亿', '万亿']; $unit_index = 0; // 处理负数 $is_negative = $number < 0; $number = abs($number); // 根据数值大小选择合适的单位 while ($number >= 10000 && $unit_index < count($units) - 1) { $number /= 10000; $unit_index++; } // 格式化数字 $formatted = round($number, $decimals); // 如果是整数且小数部分为0,则不显示小数 if ($decimals > 0 && floor($formatted) == $formatted) { $formatted = number_format($formatted, 0); } else { $formatted = number_format($formatted, $decimals, '.', ''); } return ($is_negative ? '-' : '') . $formatted . $units[$unit_index]; } /** * 千分位格式化数字 (如: 1,234,567.89) */ function formatThousandNumber($number, $decimals = 2) { return number_format($number, $decimals, '.', ','); } /** * 自定义格式化数字 */ function formatCustomNumber($number, $options = []) { $defaults = [ 'decimals' => 2, 'decimal_point' => '.', 'thousands_sep' => ',', 'suffix' => '', 'prefix' => '' ]; $options = array_merge($defaults, $options); $formatted = number_format($number, $options['decimals'], $options['decimal_point'], $options['thousands_sep']); return $options['prefix'] . $formatted . $options['suffix']; } /** * 简化版本的数字格式化 (改进原方法) * @param int|float $number 需要格式化的数字 * @param int $decimals 小数位数 * @return string 格式化后的数字字符串 */ function simpleNumberFormat($number, $decimals = 2) { if (!is_numeric($number)) { return '0'; } // 处理负数 $is_negative = $number < 0; $number = abs($number); if ($number >= 100000000) { // 1亿以上 $result = round($number / 100000000, $decimals) . '亿'; } elseif ($number >= 10000) { // 1万以上 $result = round($number / 10000, $decimals) . 'w'; } elseif ($number >= 1000) { // 1千以上 $result = round($number / 1000, $decimals) . 'k'; } else { $result = round($number, $decimals); // 如果是整数且小数部分为0,则不显示小数 if (floor($result) == $result) { $result = (int)$result; } } return ($is_negative ? '-' : '') . $result; } function generateRandomRoomName() { // 扩展形容词数组 (120+) $adjectives = [ '梦幻', '激情', '快乐', '神秘', '闪耀', '疯狂', '甜蜜', '奇幻', '魅力', '元气', '星光', '欢乐', '动感', '炫酷', '温馨', '治愈', '唯美', '热血', '浪漫', '电音', '古风', '赛博', '极速', '狂野', '静谧', '深邃', '华丽', '优雅', '不羁', '活力', '俏皮', '高能', '暗黑', '蒸汽', '朋克', '清新', '魔幻', '超能', '量子', '银河', '星际', '像素', '复古', '未来', '虚拟', '霓虹', '镭射', '全息', '赛博', '金属', '火焰', '冰雪', '海洋', '森林', '沙漠', '星空', '宇宙', '极光', '流星', '月光', '日光', '黄昏', '黎明', '午夜', '闪电', '雷霆', '暴雨', '微风', '彩虹', '云雾', '樱花', '枫叶', '糖果', '巧克力', '布丁', '蛋糕', '冰淇淋', '奶茶', '咖啡', '气泡', '钻石', '黄金', '水晶', '翡翠', '琥珀', '珍珠', '丝绸', '天鹅绒', '火焰纹', '大理石', '机甲', '高达', '飞船', '火箭', '飞碟', '恐龙', '独角兽', '凤凰', '巨龙', '精灵', '天使', '恶魔', '忍者', '武士', '骑士', '海盗', '牛仔', '侦探', '特工', '法师', '巫师', '吸血鬼', '狼人', '僵尸', '外星人', '机器人', '克隆人', '变异', '基因', '数字' ]; // 扩展名词数组 (120+) $nouns = [ '直播间', '舞台', '派对', '音乐会', '小屋', '秀场', '现场', '演唱会', '电台', '工坊', '实验室', '秘境', '星球', '峡谷', '梦境', '花园', '车站', '天台', '宇宙', '城堡', '列车', '剧场', '空间站', '岛屿', '宫殿', '教堂', '书店', '咖啡馆', '酒吧', '餐厅', '厨房', '浴室', '卧室', '客厅', '阳台', '走廊', '地下室', '阁楼', '树屋', '帐篷', '飞船', '潜艇', '赛车', '摩托', '滑板', '飞毯', '魔毯', '飞船', '火箭', '卫星', '黑洞', '虫洞', '星云', '彗星', '行星', '恒星', '星座', '银河', '太阳系', '平行宇宙', '森林', '海洋', '沙漠', '雪山', '火山', '草原', '雨林', '冰川', '瀑布', '洞穴', '迷宫', '遗迹', '古堡', '神庙', '金字塔', '空中花园', '游乐场', '电影院', '水族馆', '动物园', '工作室', '画室', '琴房', '舞厅', '录音棚', '摄影棚', '直播间', '演播厅', '歌剧院', '音乐厅', '竞技场', '擂台', '球场', '跑道', '健身房', '瑜伽馆', '道场', '武馆', '魔法学校', '霍格沃茨', '网吧', '游戏厅', 'VR室', '元宇宙', '数字空间', '云平台', '服务器', '数据中心', '网络节点', '赛博空间', '咖啡馆', '茶室', '酒吧', '甜品店', '烧烤摊', '大排档', '深夜食堂', '秘密基地', '藏宝阁', '时光机' ]; // 扩展表情符号数组 (40+) $emojis = [ '🎤', '🎧', '🎮', '🎨', '🎭', '🎬', '🎯', '🎰', '🚀', '🌈', '🔥', '🌟', '💫', '❤️', '✨', '🎉', '🎊', '🎈', '🦄', '🐱', '🐯', '🦁', '🐶', '🦊', '🐼', '🐨', '🐰', '🦋', '🐢', '🐙', '👾', '🤖', '👻', '👑', '🎩', '🎮', '🕹️', '🎲', '🎯', '🎪', '🏆', '🥇', '🏅', '🎖️', '⚡', '☄️', '🌌', '🌠', '🌍', '🪐' ]; // 随机选择组件 $adj = $adjectives[array_rand($adjectives)]; $noun = $nouns[array_rand($nouns)]; // $emoji = $emojis[array_rand($emojis)]; // $emoji = ''; $number = rand(1, 9999); // 扩展到9999增加变化性 // 组合模式(增加到8种) $formats = [ "【{$adj}{$noun}】#{$number}", "{$adj}的{$noun}{$number}", "{$adj}{$noun}-{$number}", "{$adj}·{$noun}{$number}", "{$number}号{$noun}·{$adj}", "{$adj}{$noun} {$number}", "{$adj}{$noun}{$number}号直播间", "【{$number}】{$adj}{$noun}" ]; return $formats[array_rand($formats)]; } //处理充值 function handelCharge($where,$data){ //获取订单信息 $orderModel = db::name('vs_user_recharge')->where($where)->find(); if(!$orderModel){ return 0; } db::startTrans(); try{ $userModel = db::name('user_wallet')->where('user_id',$orderModel['user_id'])->find(); if(!$userModel){ return 0; } //每天任意充值金额 model('DailyTasks')->tasks_complete($orderModel['user_id'],4); //增加余额 $res = db::name('user_wallet')->where('user_id',$orderModel['user_id'])->update([ 'coin' => $userModel['coin'] + $orderModel['coin'], 'updatetime' => time() ]); if(!$res){ db::rollback(); return 0; } //修改订单状态 $res1 = db::name('vs_user_recharge')->where($where)->update([ 'pay_status' => 2, 'pay_time' => time(), 'trade_no' => $data['trade_no'], 'updatetime' => time() ]); if(!$res1){ db::rollback(); return 0; } //查询是否首充 $is_first_charge = db::name('vs_user_money_log')->where('user_id',$orderModel['user_id'])->where('change_type',2)->where('money_type',1)->count(); //添加充值记录 $res2 = db::name('vs_user_money_log')->insert([ 'user_id' => $orderModel['user_id'], 'change_type' => 2, 'money_type' => 1, 'change_value' => $orderModel['coin'], 'from_id' => $orderModel['rid'], 'remarks' => '充值', 'createtime' => time() ]); if(!$res2){ db::rollback(); return 0; } //给上级返佣 //获取上级 $invited_user_id = db::name('vs_user_invited')->where('sub_user_id', $orderModel['user_id'])->value('user_id'); if($invited_user_id){ $re3 = model('Invited')->invited_reward($orderModel['user_id'],$orderModel['coin']); if($re3['code'] != 1){ db::rollback(); return 0; } } db::commit(); //首充 if($is_first_charge == 0){ model('Activities')->first_charge_gift_send($orderModel['user_id'],$orderModel['money']); } //天降好礼 model('Activities')->drop_gift_send($orderModel['user_id'],$orderModel['money']); return 1; } catch (\Exception $e){ db::rollback(); return 0; } } //计算收益 10% 因为金币10 = 1元 收益 1钻石 = 1元 // @param $all_gift_price 礼物总价单位金币 // @param $ratio 收益比例 // @return int 收益单位钻石 function coin_earning($all_gift_price,$ratio){ //rmb_coin_ratio 人民币转换金币的比例 //金币转换人民币 //小数点保留4位 $result = $all_gift_price * $ratio / 100 / get_system_config_value('rmb_coin_ratio'); return round($result, 4); } /** * 生成一个随机的中国大陆手机号码(仅用于测试)。 * * @return string 生成的随机手机号 */ function generateRandomPhoneNumber() { $prefix = array("131", "141", "153", "164", "178", "189", "192"); $randomPrefix = $prefix[array_rand($prefix)]; $randomNumber = mt_rand(1000, 9999) . mt_rand(1000, 9999); return $randomPrefix . $randomNumber; } //计算二维数组的一维数组个数 function array_count_dim($array) { $count = 0; foreach ($array as &$value) { $count++; } return $count; } /** * 根据身份证号码判断是否已满18岁。 * * @param string $id 身份证号码(支持15位或18位格式) * @return bool 如果年龄大于等于18岁返回 true,否则返回 false */ function getAgeId($id){ if(empty($id)){ return false; } $idcard_len = strlen($id); if(!in_array($idcard_len,array(15,18))){ return false; } $date = strtotime(substr($id, 6, 8)); $today = strtotime('today'); $diff = floor(($today - $date) / 86400 / 364); $age = strtotime(substr($id, 6, 8) . '+' . $diff . 'years') > $today ? ($diff + 1) : $diff; $age = (int)$age; if($age >= 18){ return true; }else{ return false; } } function getMillisecond() { list($s1, $s2) = explode(' ', microtime()); return (float)sprintf('%.0f', (floatval($s1) + floatval($s2)) * 1000); } /* * 写入日志到redis * @param string $key 日志key * @param array $logData 日志数据 */ function write_log_redis($key = 'log',$logData = [],$time = 7){ $redis = new \Redis(); // 连接到Redis服务器 $redis->connect(config('redis.host'), config('redis.port')); // 根据实际配置调整主机和端口 // 选择数据库2 $redis->select(2); $key = $key.'_'.date('Y-m-d-H-i-s'); $expire = 86400 * $time; $redis->setex($key, $expire, json_encode($logData)); }