= 1024 && $i < 6; $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 { $model = $v['name'] ? \think\Db::name($v['name']) : \think\Db::table($v['table']); } $primary = $v['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); $replaced = []; $count = 0; //判断是否是对象 if (is_resource($data) || is_object($data)) { return var_export($data, $return); } //判断是否有特殊的键名 $specialKey = false; array_walk_recursive($data, function (&$value, &$key) use (&$specialKey) { if (is_string($key) && (stripos($key, "\n") !== false || stripos($key, "array (") !== false)) { $specialKey = true; } }); if ($specialKey) { return var_export($data, $return); } array_walk_recursive($data, function (&$value, &$key) use (&$replaced, &$count, &$stringcheck) { if (is_object($value) || is_resource($value)) { $replaced[$count] = var_export($value, true); $value = "##<{$count}>##"; } else { if (is_string($value) && (stripos($value, "\n") !== false || stripos($value, "array (") !== false)) { $index = array_search($value, $replaced); if ($index === false) { $replaced[$count] = var_export($value, true); $value = "##<{$count}>##"; } else { $value = "##<{$index}>##"; } } } $count++; }); $dump = var_export($data, true); $dump = preg_replace('#(?:\A|\n)([ ]*)array \(#i', '[', $dump); // Starts $dump = preg_replace('#\n([ ]*)\),#', "\n$1],", $dump); // Ends $dump = preg_replace('#=> \[\n\s+\],\n#', "=> [],\n", $dump); // Empties $dump = preg_replace('#\)$#', "]", $dump); //End if ($replaced) { $dump = preg_replace_callback("/'##<(\d+)>##'/", function ($matches) use ($replaced) { return $replaced[$matches[1]] ?? "''"; }, $dump); } if ($return === true) { return $dump; } else { echo $dump; } } } 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,}\.){1,}[a-z]{2,8})(?:\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; } } /** * 格式化数字 * @param int $number 要格式化的数字 * @return string 格式化后的字符串 */ function formatNumber($number) { $length = strlen($number); //数字长度 if($length > 8){ //亿单位 $str = substr_replace(strstr($number,substr($number,-7),' '),'.',-1,0)."亿"; }elseif($length >4){ //万单位 //截取前俩为 $str = substr_replace(strstr($number,substr($number,-3),' '),'.',-1,0)."万"; }elseif($length >3){ //千单位 //截取前俩为 $str = substr_replace(strstr($number,substr($number,-2),' '),'.',-1,0)."K"; }else{ return $number; } return $str; } // 公共接口调用方法 function callApi($url, $cookie = '', $userAgent = '') { $curl = curl_init($url); // 设置选项 curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); // 将响应保存到变量而不是直接输出 curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); // 跟随重定向 curl_setopt($curl,CURLOPT_SSL_VERIFYPEER, false); //这个是重点。 // 设置请求头部信息 $headers = [ 'Content-Type: application/json', 'Accept: application/json', 'Access-Control-Allow-Origin: *', // 允许跨域请求 ]; if (!empty($userAgent)) { $headers[] = "User-Agent: {$userAgent}"; } curl_setopt($curl, CURLOPT_HTTPHEADER, $headers); // 设置 Cookie if (!empty($cookie)) { curl_setopt($curl, CURLOPT_COOKIE, $cookie); } $response = curl_exec($curl); if(curl_errno($curl)) { $error_message = curl_error($curl); } // 获取响应状态码 $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE); curl_close($curl); // 返回响应结果 if ($statusCode >= 200 && $statusCode < 300 && !empty($response)) { return $response; } else { return false; // return $response; } } // 数据写入文件txt方法 function writeToTxt($filePath, $data) { if (file_exists($filePath)) { // 如果文件存在,覆盖写入内容 if (file_put_contents($filePath, $data) !== false) { return true; // 写入成功,返回 true } else { return false; // 写入失败,返回 false } } else { // 如果文件不存在,创建并写入 $fileHandle = fopen($filePath, "w+"); if ($fileHandle) { if (fwrite($fileHandle, $data . "\n") !== false) { fclose($fileHandle); // 关闭文件指针 return true; // 写入成功,返回 true } else { fclose($fileHandle); // 关闭文件指针 return false; // 写入失败,返回 false } } else { return false; // 创建文件失败,返回 false } } } /** * 高亮显示关键词 * @param string $text 文章内容 * @param array $keywords 关键词数组 * @return string 高亮显示后的文章内容 */ function words($text, $keyword) { $highlightedString = str_replace($keyword, ''.$keyword.'', $text); return $highlightedString; } // 替换字符串指定字符 function replaceComma($inputString,$str = ',',$str1 = '、') { $outputString = str_replace($str,$str1, $inputString); return $outputString; } // 分割 function splitString($string, $delimiters) { $pattern = '/[' . preg_quote(implode("", $delimiters), '/') . ']+/'; return preg_split($pattern, $string, -1, PREG_SPLIT_NO_EMPTY); } // 将15位身份证号码改成18位 function convertTo18IDCard($idCard15) { $idCard17 = substr($idCard15, 0, 6) . '19' . substr($idCard15, 6); $idCard17Array = str_split($idCard17); $wi = [7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2]; $vi = ['1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2']; $sum = 0; for ($i = 0; $i < 17; $i++) { $sum += $idCard17Array[$i] * $wi[$i]; } $mod = $sum % 11; $idCard18 = $idCard17 . $vi[$mod]; return $idCard18; } /** * 人民币小写转大写 * * @param string $number 待处理数值 * @param bool $is_round 小数是否四舍五入,默认"四舍五入" * @param string $int_unit 币种单位,默认"元" * @return string */ function rmbToUpperCase($num = 0, $is_round = false, $int_unit = '元') { $chs = array (0, '壹', '贰', '叁', '肆', '伍', '陆', '柒', '捌', '玖'); $uni = array ('', '拾', '佰', '仟' ); $dec_uni = array ('角', '分' ); $exp = array ('','万','亿'); $res = ''; // 以 元为单位分割 $parts = explode ( '.', $num, 2 ); $int = isset ( $parts [0] ) ? strval ( $parts [0] ) : 0; $dec = isset ( $parts [1] ) ? strval ( $parts [1] ) : ''; // 处理小数点 $dec_len = strlen ( $dec ); if (isset ( $parts [1] ) && $dec_len > 2) { $dec = $is_round ? substr ( strrchr ( strval ( round ( floatval ( "0." . $dec ), 2 ) ), '.' ), 1 ) : substr ( $parts [1], 0, 2 ); } // number= 0.00时,直接返回 0 if (empty ( $int ) && empty ( $dec )) { return '零'; } // 整数部分 从右向左 for($i = strlen ( $int ) - 1, $t = 0; $i >= 0; $t++) { $str = ''; // 每4字为一段进行转化 // for($j = 0; $j < 4 && $i >= 0; $j ++, $i --) { // $u = $int{$i} > 0 ? $uni [$j] : ''; // $str = $chs[$int[$i]] . $u . $str; // } for ($j = 0; $j < 4 && $i >= 0; $j++, $i--) { $u = $int[$i] > 0 ? $uni[$j] : ''; $str = $chs[$int[$i]] . $u . $str; } $str = rtrim ( $str, '0' ); $str = preg_replace ( "/0+/", "零", $str ); $u2 = $str != '' ? $exp [$t] : ''; $res = $str . $u2 . $res; } $dec = rtrim ( $dec, '0' ); // 小数部分 从左向右 if (!empty ( $dec )) { $res .= $int_unit; $cnt = strlen ( $dec ); for ($i = 0; $i < $cnt; $i++) { $u = $dec[$i] > 0 ? $dec_uni[$i] : ''; // 非0的数字后面添加单位 $res .= $chs[$dec[$i]] . $u; } if ($cnt == 1) $res .= '整'; $res = rtrim ( $res, '0' ); // 去掉末尾的0 $res = preg_replace ( "/0+/", "零", $res ); // 替换多个连续的0 } else { $res .= $int_unit . '整'; } return $res; } // 阿拉伯数字转美元大写 function numberToWords($number) { $decimal = round($number - ($no = floor($number)), 2) * 100; $hundred = null; $digits_length = strlen($no); $i = 0; $str = array(); $words = array(0 => '', 1 => 'ONE', 2 => 'TWO', 3 => 'THREE', 4 => 'FOUR', 5 => 'FIVE', 6 => 'SIX', 7 => 'SEVEN', 8 => 'EIGHT', 9 => 'NINE', 10 => 'TEN', 11 => 'ELEVEN', 12 => 'TWELVE', 13 => 'THIRTEEN', 14 => 'FOURTEEN', 15 => 'FIFTEEN', 16 => 'SIXTEEN', 17 => 'SEVENTEEN', 18 => 'EIGHTEEN', 19 => 'NINETEEN', 20 => 'TWENTY', 30 => 'THIRTY', 40 => 'FORTY', 50 => 'FIFTY', 60 => 'SIXTY', 70 => 'SEVENTY', 80 => 'EIGHTY', 90 => 'NINETY'); $digits = array('', 'HUNDRED', 'THOUSAND', 'LAC', 'CRORE'); while ($i < $digits_length) { $divider = ($i == 2) ? 10 : 100; $number = floor($no % $divider); $no = floor($no / $divider); $i += ($divider == 10) ? 1 : 2; if ($number) { $plural = (($counter = count($str)) && $number > 9) ? 'S' : null; $hundred = ($counter == 1 && $str[0]) ? ' AND ' : null; $str [] = ($number < 21) ? $words[$number] . " " . $digits[$counter] . $plural . " " . $hundred : $words[floor($number / 10) * 10] . " " . $words[$number % 10] . " " . $digits[$counter] . $plural . " " . $hundred; } else $str[] = null; } $str = array_reverse($str); $result = implode('', $str); if ($decimal > 0) { $result .= " AND CENTS "; if ($decimal < 10) { $result .= $words[$decimal]; } else { $result .= $words[floor($decimal / 10) * 10]; $result .= " " . $words[$decimal % 10]; } } return 'SAY US DOLLARS ' . $result . ' ONLY'; } // 长度单位换算 function lengthConversion($value, $unit) { // 定义单位之间的换算关系 $conversionTable = [ 'km' => 1000, // 千米 'm' => 1, // 米 'dm' => 0.1, // 分米 'cm' => 0.01, // 厘米 'li' => 500, // 里 'zhang' => 3.33333, // 丈 'chi' => 0.33333, // 尺 'cun' => 0.03333, // 寸 'fen' => 0.00333, // 分 'li2' => 0.000333, // 厘 'nmi' => 1852, // 海里 'fathom' => 1.8288, // 英寻 'mile' => 1609.344, // 英里 'fur' => 201.168, // 弗隆 'yd' => 0.9144, // 码 'ft' => 0.3048, // 英尺 'ins' => 0.0254, // 英寸 'mm' => 0.001, // 毫米 'um' => 0.000001 // 微米 ]; // 转换为转换单位 $baseValue = $value * $conversionTable[$unit]; // 构建输出数组 $result = []; foreach ($conversionTable as $key => $conversionValue) { if ($conversionValue === 1) { $result[$key] = intval($baseValue); } else { $result[$key] = round($baseValue / $conversionValue, 8); } } return $result; } // 温度单位换算 function convertTemperature($value, $unit) { $result = []; switch ($unit) { case 'c': // 摄氏度 $result['c'] = $value; // 华氏度 $result['f'] = ($value * 9/5) + 32; // 开氏度 $result['k'] = $value + 273.15; // 兰氏度 $result['ra'] = ($value + 273.15) * 9/5; // 列氏度 $result['re'] = $value * 4/5; break; case 'f': // 摄氏度 $result['c'] = ($value - 32) * 5/9; // 华氏度 $result['f'] = $value; // 开氏度 $result['k'] = ($value + 459.67) * 5/9; // 兰氏度 $result['ra'] = $value + 459.67; // 列氏度 $result['re'] = ($value - 32) * 4/9; break; case 'k': // 摄氏度 $result['c'] = $value - 273.15; // 华氏度 $result['f'] = ($value * 9/5) - 459.67; // 开氏度 $result['k'] = $value; // 兰氏度 $result['ra'] = $value * 9/5; // 列氏度 $result['re'] = ($value - 273.15) * 4/5; break; case 'ra': // 摄氏度 $result['c'] = ($value - 491.67) * 5/9; // 华氏度 $result['f'] = $value - 459.67; // 开氏度 $result['k'] = $value * 5/9; // 兰氏度 $result['ra'] = $value; // 列氏度 $result['re'] = ($value - 491.67) * 4/9; break; case 're': // 摄氏度 $result['c'] = $value * 5/4; // 华氏度 $result['f'] = ($value * 9/4) + 32; // 开氏度 $result['k'] = ($value * 5/4) + 273.15; // 兰氏度 $result['ra'] = ($value * 9/4) + 491.67; // 列氏度 $result['re'] = $value; break; default: return false; } // 对$result数组中的每个值进行变量转换 foreach($result as &$item) { if (is_numeric($item)) { $item = floatval($item); if (floor($item) == $item) { $item = intval($item); } else { $item = round($item, 2); } } } return $result; } // 功率单位换算 function convertPower($value, $fromUnit) { $units = array( 'w' => 1, // 瓦特(W) 'kw' => 1000, // 千瓦(kW) 'hp' => 735.49875, // 马力(HP) 'ps' => 735.49875, // 百分力马力(PS) 'kg' => 9.80665, // 公斤·米/秒(kg·m/s) 'kcal' => 4186.8, // 千卡/秒(kcal/s) 'btu' => 1055.056, // 英热单位/秒(Btu/s) 'ft' => 1.355818, // 英尺·磅/秒(ft·lb/s) 'j' => 1, // 焦耳/秒(J/s) 'nm' => 1 // 牛顿·米/秒(N·m/s) ); if (!isset($units[$fromUnit])) { return false; // 无效的单位 } $results = []; foreach ($units as $unit => $conversionFactor) { $convertedValue = $value * ($units[$fromUnit] / $conversionFactor); // 转换为 float 类型,并保留小数点后 7 位数字 $roundedValue = round(floatval($convertedValue), 7); $results[$unit] = $roundedValue; } return $results; } // 速度单位换算 function convertSpeed($value, $fromUnit) { $units = array( 'm' => 1, // 米/秒(m/s) 'km' => 3.6, // 千米/时(km/h) 'mach' => 343.2, // 马赫(mach) 'ins' => 0.0254, // 英寸/秒(in/s) 'kms' => 1000, // 千米/秒(km/s) 'c' => 299792458, // 光速(c) 'mile' => 0.44704, // 英里/时(mile/h) 'knot' => 0.514444, // 节(knot) 'ly' => 9.461e+12 // 光年/年(ly/y) ); $fromUnit = strtolower($fromUnit); // 将输入的单位转换为小写字母 if (!isset($units[$fromUnit])) { return false; // 无效的单位 } $results = []; foreach ($units as $unit => $conversionFactor) { $convertedValue = $value * ($units[$fromUnit] / $conversionFactor); // 使用 sprintf() 函数将结果格式化为字符串,并限定小数点后位数为 12 $formattedValue = sprintf('%0.12f', $convertedValue); $results[$unit] = (float) $formattedValue; } return $results; } // 重量单位换算 function convertWeight($value, $fromUnit) { $conversionTable = [ 'tonne' => 1e6, // 吨 'kilogram' => 1e3, // 公斤 'gram' => 1, // 克 'milligram' => 1e-3, // 毫克 'shijin' => 500, // 市斤 'dan' => 50000, // 担 'liang' => 50, // 两 'qian' => 5, // 钱 'jhb' => 373.242, // 金衡磅 'jhas' => 31.1035, // 金衡盎司 'dwt' => 1.555174, // 英钱 'jhgl' => 0.06479891, // 金衡格令 'ycd' => 1016046.9, // (英制)长吨 'mdd' => 907184.74, // (美制)短吨 'cwt' => 50802.345, // 英担 'cwts' => 45359.237, // 美担 'ys' => 6350.293, // 英石 'lb' => 453.59237, // 磅 'oz' => 28.349523125, // 盎司 'dr' => 1.7718451953125, // 打兰 'gl' => 0.06479891 // 格令 ]; $fromUnit = strtolower($fromUnit); if (!array_key_exists($fromUnit, $conversionTable)) { return false; } $fromValue = $value * $conversionTable[$fromUnit]; $results = []; foreach ($conversionTable as $toUnit => $conversion) { $result = $fromValue / $conversion; $results[$toUnit] = $result; } return $results; } // 面积单位换算 function convertArea($value, $unit) { // 定义各单位与平方米的换算关系 $conversion = [ 'km2' => 1, // 平方千米 'ha' => 100, // 公顷 'mu' => 1500, // 亩 'm2' => 1000000, // 平方米 'dm2' => 100000000, // 平方分米 'cm2' => 10000000000, // 平方厘米 'mm2' => 1000000000000, // 平方毫米 'sqmi' => 0.386102, // 平方英里 'acre' => 247.105381, // 英亩 'sqrd' => 39536.8670851, // 平方竿 'sqyd' => 1195990.046301, // 平方码 'sqft' => 10763910.41671, // 平方英尺 'sqin' => 1550003100.0062 // 平方英寸 ]; // 检查输入的单位是否合法 if (!array_key_exists($unit, $conversion)) { return false; } $results = []; // 遍历每一个单位并进行换算 foreach ($conversion as $key => $factor) { $result = $value * $factor; $results[$key] = $result; } return $results; } // 体积单位换算 function convertVolume($value, $unit) { // 定义单位之间的换算关系 $conversionTable = [ // 公制单位 'm3' => 1, //立方米(m3) 'hl' => 0.1, // 公石(hl) 'dal' => 0.01, // 十升(dal) 'dm3' => 0.001, // 立方分米(dm3)=升(l) 'dl' => 0.0001, // 分升(dl) 'cl' => 0.00001, // 厘升(cl) 'cm3' => 0.000001, // 立方厘米(cm3)=毫升(ml) 'mm3' => 0.000000001, // 立方毫米(mm3) // 美制干量 'tong' => 0.1156281985, // 捅 'bu' => 0.03523907, // 蒲式耳 'pk' => 0.0088097678571429, // 配克 'qt' => 0.00110122094271, // 夸脱 'pt' => 0.000550610471, // 品脱 // 英制液量和干量 'tongs' => 0.163659239925, // 捅 'bus' => 0.036368719997, // 蒲式耳 'bal' => 0.00454609, // 加仑 'pts' => 0.00056826125, // 品脱(pt) 'floz' => 0.0000284130625, // 液体盎司 // 公制烹调制式 'tablespoon' => 0.000015, // 大汤匙 'teaspoon' => 0.000005, // 调羹 // 美制烹调制式 'tbs' => 0.00001478676, // 汤匙 'tsp' => 0.000004928922, // 茶匙 'flozs' => 0.000236588237, // 杯 // 美制液量 'tongss' => 0.158987294939, // 桶[42加仑] 'gal' => 0.00378541, // 加仑(gal) 'qts' => 0.00094635295, // 夸脱(qt) 'ptss' => 0.000473176475, // 品脱(pt) 'gi' => 0.00011829411825, // 及耳(gi) 'flozss' => 0.00002957353, // 液量盎司(fl oz) 'fldr' => 0.000003696691, // 液体打兰 'min' => 0.0000000004813399993896500, // 量滴(min) // 美英同制体积计量 'acrefoot' => 1233.4818375, // 亩英尺 'cubicyard' => 0.764554858, // 立方码 'cubicfoot' => 0.028316846592, // 立方英尺 'cubicinch' => 0.000016387064, // 立方英寸 ]; // 检查输入单位是否支持 if (!isset($conversionTable[$unit])) { return false; } $results = []; // 遍历所有单位进行换算 foreach ($conversionTable as $targetUnit => $conversionFactor) { $result = $value * $conversionTable[$unit] / $conversionFactor; $results[$targetUnit] = $result; } return $results; } // 压力单位换算 function convertPressure($value, $fromUnit) { // 建立单位间的换算因子数组 $conversionFactors = [ 'bar' => 1, 'kpa' => 100, 'hpa' => 1000, 'mbar' => 1000, 'pa' => 100000, 'atm' => 0.986923, 'mmhg' => 750.06168, 'lbfft2' => 2088.5435, 'lbfin2' => 14.50377, 'inhg' => 29.529988, 'kgfcm2' => 1.0197162, 'kgfm2' => 10197.162, 'mmh2O' => 10197.2 ]; // 检查输入单位是否存在 if (!array_key_exists($fromUnit, $conversionFactors)) { return false; } $convertedValues = []; // 遍历转换因子数组进行单位换算 foreach ($conversionFactors as $unit => $factor) { $convertedValue = $value * ($factor / $conversionFactors[$fromUnit]); $convertedValues[$unit] = $convertedValue; } return $convertedValues; } // 油耗计算 function calculateFuelConsumption($oilPrice, $moneySpent, $distance) { // 计算总油耗量(升) $totalFuel = $moneySpent / $oilPrice; // 计算百公里油耗(升/公里),四舍五入保留一位小数 $fuelConsumptionPer100km = round(($totalFuel / $distance) * 100, 2); // 计算每公里油耗(元/公里),四舍五入保留一位小数 $fuelCostPerKm = round($moneySpent / $distance, 2); // 返回结果数组 $result = array( 'fuelConsumptionPer100km' => $fuelConsumptionPer100km, 'fuelCostPerKm' => $fuelCostPerKm ); return $result; } // 房贷计算器 function calculateLoan($principal, $loanTerm, $repaymentMethod, $firstRepaymentMonth, $interestMode, $lprRate, $bpRate, $interestDiscount) { // 将百分比的 LPR 利率转换为小数形式 $lprRate = $lprRate / 100; // 根据利率模式计算实际利率 if ($interestMode == 'LPR+BP') { // 计算 LPR+BP 模式下的基准利率 $baseInterestRate = $lprRate + $bpRate; // 计算带入利率折扣后的实际利率 $actualInterestRate = $baseInterestRate * $interestDiscount; } else { // 固定利率模式下使用 LPR+BP 中的基本利率 $baseInterestRate = $lprRate + $bpRate; // 固定利率模式下不考虑利率折扣 $actualInterestRate = $baseInterestRate; } // 将年利率转换为月利率 $monthlyInterestRate = $actualInterestRate / 12; // 初始化还款明细数组 $repaymentDetails = array(); // 计算每月还款额 if ($repaymentMethod == '等额本金') { // 等额本金方式下,每月还款额固定 $monthlyPrincipalPayment = $principal / $loanTerm; $monthlyPayment = $monthlyPrincipalPayment + $principal * $monthlyInterestRate; } else { // 等额本息方式下,使用等额本息公式计算每月还款额 $monthlyPayment = ($principal * $monthlyInterestRate * pow(1 + $monthlyInterestRate, $loanTerm)) / (pow(1 + $monthlyInterestRate, $loanTerm) - 1); $monthlyPrincipalPayment = $monthlyPayment - $principal * $monthlyInterestRate; } // 计算总还款额、总利息和剩余本金 $totalPayment = 0; $totalInterest = 0; $remainingPrincipal = $principal; // 循环计算还款明细 for ($i = 1; $i <= $loanTerm; $i++) { // 计算每月还息额 $interestPayment = $remainingPrincipal * $monthlyInterestRate; // 计算每月还本金额 $principalPayment = $monthlyPrincipalPayment; // 更新剩余本金 $remainingPrincipal -= $principalPayment; // 构建还款明细数组 $repaymentDetails[] = array( '期数' => $i, '月份' => date('Y年m月', strtotime($firstRepaymentMonth . ' +' . ($i - 1) . ' month')), '每月总还款(元)' => $monthlyPayment, '每月还息(元)' => $interestPayment, '每月还本金(元)' => $principalPayment, '剩余本金(元)' => $remainingPrincipal ); // 累加总还款额和总利息 $totalPayment += $monthlyPayment; $totalInterest += $interestPayment; } // 返回计算结果 return array( '总利息' => $totalInterest, '每月总还款(月供)' => $monthlyPayment, '还款明细数组' => $repaymentDetails ); } // BIM计算器 function calculateAndClassifyBMI($weight, $height) { // 转换身高单位为米 $height = $height / 100; // 计算 BMI $bmi = $weight / ($height * $height); if(strpos($bmi, '.') !== false){ // 如果有小数点,则四舍五入保留一位小数 $bmi = round($bmi, 1); } // 计算理想体重 $idealWeight = $height * $height * 21.7; if (strpos($idealWeight, '.') !== false) { // 如果有小数点,则四舍五入保留一位小数 $idealWeight = round($idealWeight, 1); } // 分类 BMI if($bmi < 15){ $classification = "您太瘦,应去做个体检,增加营养。"; } else if ($bmi >= 15 && $bmi <= 18.4) { $classification = "您过度苗条,应增加营养和锻炼。"; } elseif ($bmi >= 18.4 && $bmi < 22) { $classification = "恭喜!!您是标准身材,注意保持。"; } elseif ($bmi >= 22 && $bmi <= 25) { $classification = "您是健康体重,但已不苗条,小心。"; } elseif ($bmi >= 25 && $bmi < 30) { $classification = "您超重了,应该立即减肥!"; } elseif ($bmi >= 30 && $bmi <= 40) { $classification = "您很胖,减肥已是您的头等大事!"; } else if($bmi > 40){ $classification = "您非常胖,肥胖将危及您的健康!"; } return [ 'bmi' => $bmi, // bim指数 'suggest' => $classification,//建议 'idealWeight' => $idealWeight // 理想体重 ]; } // 去掉字符串中的html function stripHtml($content){ $content = strip_tags($content); $content = str_replace("\r\n", '', $content); $content = str_replace("\t", '', $content); $content = str_replace("\r", '', $content); $content = str_replace("\n", '', $content); $content = str_replace(" ", '', $content); $content = html_entity_decode($content); // 将 HTML 实体转换为相应的字符 $content = preg_replace('/\s+/u', '', $content); // 去除所有空白字符 return trim($content); } // 匹配符号分割为数组 function tags($str){ $separator = ',、,-_|'; // 自定义的分隔符,包含逗号和顿号 $data = preg_split("/[" . preg_quote($separator) . "]/u", $str); return $data; } // 百度主动推送 function baidupush($url){ $urls = [Request::instance()->domain().$url]; $api = 'http://data.zz.baidu.com/urls?site='.Request::instance()->domain().'&token='.Config::get('site.baidutoken'); $ch = curl_init(); $options = array( CURLOPT_URL => $api, CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => implode("\n", $urls), CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), ); curl_setopt_array($ch, $options); $result = curl_exec($ch); return $result; } // 必应推送 function biyingpush($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://ssl.bing.com//webmaster/api.svc/json/SubmitUrlbatch?apikey=".Config::get('site.biyingtoken')); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([ 'siteUrl' => Request::instance()->domain(), 'urlList' => [Request::instance()->domain().$url] ])); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_HTTPHEADER, [ 'Host: ssl.bing.com', 'Content-Type: application/json; charset=utf-8' ]); $response = curl_exec($ch); $http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); if ($http_code == 200 && json_decode($response)->d == null) { return "推送成功"; foreach ($url_list as $url) { return $url; } } else { return "推送失败:推送配额不足"; } } // 神马推送 function shenmapush($url) { $urls = [Request::instance()->domain().$url]; $api = 'https://data.zhanzhang.sm.cn/push?site='.Request::instance()->host().'&user_name='.Config::get('site.shenma_user').'&resource_name=mip_add&token='.Config::get('site.authkey'); $ch = curl_init(); $options = array( CURLOPT_URL => $api, CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_POSTFIELDS => implode("\n", $urls), CURLOPT_HTTPHEADER => array('Content-Type: text/plain'), ); curl_setopt_array($ch, $options); $result = json_decode(curl_exec($ch)); if(empty($result->returnCode)){ return '推送失败';exit(); } if($result->returnCode == 200){ return '推送成功';exit(); } if($result->returnCode == 201){ return 'token不合法';exit(); } if($result->returnCode == 202){ return '当日流量已用完';exit(); } if($result->returnCode == 400){ return '请求参数有误';exit(); } if($result->returnCode == 500){ return '服务器内部错误';exit(); } } // 截取指定字符串 function cut_str($str,$length){ return mb_substr($str,0,$length,'UTF-8').'...'; } // 蜘蛛访问记录 function Get_Spider() { $bot = ''; $request = Request::instance(); $userAgent = strtolower($request->header('user-agent')); $ip = $request->ip(); if (stripos($userAgent,'Baiduspider') !== false) { $bot = '百度'; } elseif (stripos($userAgent,'Sogou') !== false) { $bot = '搜狗'; } elseif (stripos($userAgent,'bingbot') !== false) { $bot = '必应'; }elseif (stripos($userAgent,'360Spider') !== false) { $bot = '360'; }elseif (stripos($userAgent,'Bytespider') !== false) { $bot = '头条'; }elseif(stripos($userAgent,'YisouSpider') !== false){ $bot = '神马'; }elseif(stripos($userAgent,'Googlebot') !== false){ $bot = '谷歌'; }elseif(stripos($userAgent,'Amazonbot') !== false){ $bot = '亚马逊'; } // 如果是蜘蛛就存入数据库 if (!empty($bot)) { Db::name('spiders')->insert(['name' => $bot,'ip' => $ip,'ua' => $userAgent,'createtime' => time()]); } } // 多久之前 function formatTime($timestamp) { $currentTime = time(); $timeDiff = $currentTime - $timestamp; if ($timeDiff < 60) { return '刚刚'; } elseif ($timeDiff < 3600) { $minutes = floor($timeDiff / 60); return $minutes . '分钟之前'; } elseif ($timeDiff < 86400) { $hours = floor($timeDiff / 3600); return $hours . '小时之前'; } elseif ($timeDiff < 2592000) { $days = floor($timeDiff / 86400); return $days . '天之前'; } elseif ($timeDiff < 31536000) { $months = floor($timeDiff / 2592000); return $months . '个月之前'; } else { return date('Y-m-d', $timestamp); } } // 截取出域名 function urls($url) { $parsedUrl = parse_url($url); return $parsedUrl['host']; } // 字符串长度 function strlength($str){ $strs = mb_strlen($str,'utf8'); return $strs; } function getDateArray($start, $end) { $dateArray = []; for ($date = $start; $date <= $end; $date = strtotime("+1 day", $date)) { $day = date("j", $date); $dateArray[] = $day; } return $dateArray; } function getBrowserOs() { $flag = $_SERVER['HTTP_USER_AGENT']; if (preg_match('/Windows[\d\. \w]*/', $flag, $match)) { $sys = $match[0]; } else { $sys = 'Unknown'; } // 检查操作系统 if (preg_match('/Chrome\/[\d\.\w]*/', $flag, $match)) { // 检查Chrome $browser = $match[0]; } elseif (preg_match('/Safari\/[\d\.\w]*/', $flag, $match)) { // 检查Safari $browser = $match[0]; } elseif (preg_match('/MSIE [\d\.\w]*/', $flag, $match)) { // IE $browser = $match[0]; } elseif (preg_match('/Opera\/[\d\.\w]*/', $flag, $match)) { // opera $browser = $match[0]; } elseif (preg_match('/Firefox\/[\d\.\w]*/', $flag, $match)) { // Firefox $browser = $match[0]; } elseif (preg_match('/OmniWeb\/(v*)([^\s|;]+)/i', $flag, $match)) { //OmniWeb $browser = $match[2]; } elseif (preg_match('/Netscape([\d]*)\/([^\s]+)/i', $flag, $match)) { //Netscape $browser = $match[2]; } elseif (preg_match('/Lynx\/([^\s]+)/i', $flag, $match)) { //Lynx $browser = $match[1]; } elseif (preg_match('/360SE/i', $flag, $match)) { //360SE $browser = '360安全浏览器'; } elseif (preg_match('/SE 2.x/i', $flag, $match)) { //搜狗 $browser = '搜狗浏览器'; } else { $browser = 'unkown'; } return [$sys, $browser]; } function getip($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]; } // 字符串编码转换 function strToUTF8($strText) { $encode = mb_detect_encoding($strText, array('UTF-8', 'GB2312', 'GBK')); if ($encode != "UTF-8") { return @iconv($encode, 'UTF-8', $strText); } else { return $strText; } } // 设置缓存类型 function setCache() { // 判断是否开启缓存 if(Config::get('site.cacheSwitch')){ $config = [ 'type' => Config::get('site.cacheType'), 'expire' => Config::get('site.cacheInt') ]; return $config; }else{ return false; } } // 获取域名地址等信息 function Site_Request($type) { $request = Request::instance(); if(empty($type) || !isset($type)){ return '参数错误'; } if($type == 'domain'){ // 获取当前域名 return $request->domain(); }else if($type == 'file') { // 获取当前入口文件 return $request->baseFile(); }else if($type == 'url') { // 获取当前URL地址 不含域名 return $request->url(); }else if($type == 'url with domain'){ // 获取包含域名的完整URL地址 return $request->url(true); }else if($type == 'url without query'){ // 获取当前URL地址 不含QUERY_STRING return $request->baseUrl(); }else if($type == 'root'){ // 获取URL访问的ROOT地址 return $request->root(); }else if($type == 'root with domain'){ // 获取URL访问的ROOT地址 return $request->root(true); }else if($type == 'pathinfo'){ // 获取URL地址中的PATH_INFO信息 return $request->pathinfo(); }else if($type == 'ext'){ // 获取URL地址中的后缀信息 return $request->ext(); } }