* @date: 2021-04-18 12:27 */ use Hashids\Hashids; /** * 获取分页start offset * @param $amount * @param int $page * @param int $page_size * @return int|mixed */ function get_page_start($amount, $page = 1, $page_size = 20) : int { if (empty($amount)) { return $page_size; } $page_size = empty($page_size) ? 20 : $page_size; $page_most = ceil($amount / $page_size); if (isset($page)) { $page = intval($page); if ($page > $page_most) { $page = $page_most; } } else { $page = 1; } $page = max(1, $page); //找出最大值 $start_limit = ($page - 1) * $page_size; return $start_limit; } /** * 随机生成指定长度字符串 * @param int $len 长度 * @return string */ function rand_letter($len = 18) : string { $str = ''; if ($len <= 0) { $len = 18; } $chars = "abcdefhjmnpqrstuvwxyzABCDEFGHJKLMNPQRSTUVWYXZ"; $clen = strlen($chars); $max = $clen - 1; for ($i = 0; $i < $len; $i++) { $str .= $chars[mt_rand(0, $max)]; } return $str; } /** * 随机生成指定长度字符串 * @param int $len 长度 * @return string */ function rand_str($len = 18) { $str = ''; if ($len <= 0) { $len = 18; } $chars = "abcdefhjmnpqrstuvwxyz23456789ABCDEFGHJKLMNPQRSTUVWYXZ"; $clen = strlen($chars); $max = $clen - 1; for ($i = 0; $i < $len; $i++) { $str .= $chars[mt_rand(0, $max)]; } return $str; } /** * 随机生成字符串 * @param int $length 长度 * @param int $numeric 纯数字 * @return string */ function random($length, $numeric = 0) : string { if (version_compare(PHP_VERSION, '4.2.0', '<')) { mt_srand((double)microtime() * 1000000); } else { mt_srand(); } $seed = base_convert(md5(print_r($_SERVER, 1) . microtime()), 16, $numeric ? 10 : 35); $seed = $numeric ? (str_replace('0', '', $seed) . '012340567890') : ($seed . 'zZ' . strtoupper($seed)); $hash = ''; $max = strlen($seed) - 1; for ($i = 0; $i < $length; $i++) { $hash .= $seed[mt_rand(0, $max)]; } return $hash; } /** * json响应成功 * @param mixed $data 数据 * @param string $message 消息 * @return mixed */ function json_success($data, $message = '操作成功') { $handshake = ''; $data = [ 'code' => 200, 'message' => $message, 'data' => $data, 'handshake' => $handshake, ]; return response()->json($data); } /** * json响应失败 * @param string $message 消息 * @param int $code 代码 * @return \Illuminate\Http\JsonResponse */ function json_fail($message, $code = 500, $data = []) { $handshake = ''; $data = [ 'code' => $code, 'message' => $message, 'data' => $data, 'handshake' => $handshake, ]; return response()->json($data); } /** * 字符串截取函数(按字个数) * @param string $string 需要截断的字符串 * @param int $length 允许字符串显示的最大长度(按字个数) * @param string $dot 超出的部分所用替代标识符 * @return string */ function cutstr($string, $length, $dot = '') : string { if (function_exists('mb_strcut')) { if (mb_strlen($string) > $length) { return mb_substr($string, 0, $length - mb_strlen($dot)) . $dot; } else { return $string; } } else { return cut_no_mbstring($string, $length, $dot); } } /** * 没有mbstring库字符串截取指定长度 * @param string $string 字符串 * @param int $length 截取长度 * @param string $dot 结尾的字符点点 * @param string $charset 编码 * @return string */ function cut_no_mbstring($string, $length, $dot = '', $charset = 'utf-8') { if (strlen($string) <= $length) { return $string; } $strcut = ''; if (strtolower($charset) == 'utf-8') { $n = $tn = $noc = 0; while ($n < strlen($string)) { $t = ord($string[$n]); if ($t == 9 || $t == 10 || (32 <= $t && $t <= 126)) { $tn = 1; $n++; $noc++; } elseif (194 <= $t && $t <= 223) { $tn = 2; $n += 2; $noc += 2; } elseif (224 <= $t && $t < 239) { $tn = 3; $n += 3; $noc += 2; } elseif (240 <= $t && $t <= 247) { $tn = 4; $n += 4; $noc += 2; } elseif (248 <= $t && $t <= 251) { $tn = 5; $n += 5; $noc += 2; } elseif ($t == 252 || $t == 253) { $tn = 6; $n += 6; $noc += 2; } else { $n++; } if ($noc >= $length) { break; } } if ($noc > $length) { $n -= $tn; } $strcut = substr($string, 0, $n); } else { for ($i = 0; $i < $length - strlen($dot) - 1; $i++) { $strcut .= ord($string[$i]) > 127 ? $string[$i] . $string[++$i] : $string[$i]; } } return $strcut . $dot; } /** * 获取IP信息 * @return array */ function client_ip_info() { $ip = request()->getClientIp(); $arr_ipa = \Zhuzhichao\IpLocationZh\Ip::find($ip); array_pop($arr_ipa); //剔除最后一个下标, 国标 $arr_ipa = array_filter($arr_ipa); $ip_address = !empty($arr_ipa) ? implode('|', $arr_ipa) : ''; return [ $ip, $ip_address, ]; } /** * 格式化页码入参 * @param $page * @return int */ function format_page($page) { $page = intval($page); if ($page <= 0) { $page = 1; } if ($page > PHP_INT_MAX) { $page = PHP_INT_MAX; } return $page; } /** * 密码星号加密 * @param string $str 输入的字符串 * @return string */ function pass_encode($str) { $len = strlen($str); if ($len < 1) { return ''; } $new = ''; for ($i = 0; $i < $len; $i++) { $new .= ($i == 0 || $i == $len - 1) ? $str[$i] : '*'; } return $new; } /** * 密码星号解密 * @param string $new 明文密码 * @param string $old 原始密码 * @return mixed */ function pass_decode($new, $old) { return $new == pass_encode($old) ? $old : $new; } /** * 加密手机号 * @param $mobile * @return string */ function encode_mobile($mobile) { $str = ''; if ($mobile) { $len = strlen($mobile); for ($i = 0; $i < $len; $i++) { $str .= ($i < 5 || $i > $len - 4) ? $mobile[$i] : '*'; } } return $str; } /** * 更新OpCache * 生成缓存php文件的地方都需要调用此函数 * @return void */ function opcache_update() { if (function_exists('opcache_reset')) { opcache_reset(); } } /** * 获取相对依赖双斜杠开头的URL地址 * @param $url * @return mixed */ function get_slashes_url($url) { if (preg_match('/^(http|https)\:\/\/(.*?)$/i', $url, $arr_matches)) { return '//' . $arr_matches[2]; } else { return $url; } } /** * AES 加密 * @param mixed $content 明文 * @param string $key 密钥 * @param string $iv 向量,必须为数字 * @param string $cipher 算法. * @param int $option 标记的按位或: OPENSSL_RAW_DATA=1 、 OPENSSL_ZERO_PADDING=2. * @return string */ function aes_encrypt($content, $key, $iv = '', $cipher = 'AES-256-CBC', $option = 1) { $ivLength = openssl_cipher_iv_length($cipher); // 向量长度. /*$iv = openssl_random_pseudo_bytes($ivLength); // 根据长度生成向量.*/ //$option = OPENSSL_RAW_DATA; // 标记的按位或: OPENSSL_RAW_DATA=1 、 OPENSSL_ZERO_PADDING=2. $tag = null; // 使用 AEAD 密码模式(GCM 或 CCM)时传引用的验证标签. $aad = ''; // 附加的验证数据. $tagLength = 16; // 验证 tag 的长度。GCM 模式时,它的范围是 4 到 16. $iv = (string)$iv; return @openssl_encrypt($content, $cipher, $key, $option, $iv); } /** * AES 解密 * @param string $content base64密文 * @param string $key 密钥 * @param string $iv 向量,必须为数字 * @param string $cipher 算法. * @param int $option 标记的按位或: OPENSSL_RAW_DATA=1 、 OPENSSL_ZERO_PADDING=2. * @return string */ function aes_decrypt($content, $key, $iv = '', $cipher = 'AES-256-CBC', $option = 1) { $iv = (string)$iv; return @openssl_decrypt($content, $cipher, $key, $option, $iv); } /** * 加密ID. * @param $id * @param int $length 长度 * @return string */ function hashEncodeId($id, $length = 6) { $hashids = new Hashids(config('hashids.salt', ''), 6); return $hashids->encode($id); } /** * 解密ID. * @param $str * @return string */ function hashDecodeId($str) { $hashids = new Hashids(config('hashids.salt', ''), 6); $arr = $hashids->decode($str); return implode('', $arr); } /** /** * 简单的转html代码 * @param string $str 源字符串. * @return string */ function code2html($str) { $str = str_replace("<", "<", $str); $str = str_replace(">", ">", $str); $str = str_replace(" ", " ", $str); $str = str_replace("\r\n", "
", $str); $str = str_replace("\n", "
", $str); return $str; } /** * 获取最大上传数量 * @param int $config_size 配置最大尺寸 * @return array */ function get_upload_sys_info($config_size = 0) { $get_upload_max_size_units = strtoupper(trim(ini_get("upload_max_filesize"))); //获取服务器支持最大上传文件大小 有单位 $get_upload_max_size = substr($get_upload_max_size_units,0,strlen($get_upload_max_size_units)-1); //无单位 $units = substr($get_upload_max_size_units,-1,1); //获取单位 switch($units) { //单位换算 case "G": $k_upload_max_size = $get_upload_max_size*1024*1024; break; case "M": $k_upload_max_size = $get_upload_max_size*1024; break; case "K": default: $k_upload_max_size = $get_upload_max_size; break; } $upload_max_size = $k_upload_max_size; if($config_size) { if($config_size < $k_upload_max_size) { $upload_max_size = $config_size; } } $arr = array( 'get_upload_max_size_units' => $get_upload_max_size_units, //系统有单位大小 'get_upload_max_size' => $get_upload_max_size, //系统无单位大小 'k_upload_max_size' => $k_upload_max_size, //单位为K的大小 'upload_max_size' => $upload_max_size //当前环境下大小单位K ); return $arr; } /** * 获取文件的扩展名,不包含. * @param string $filename 文件名 * @return string */ function file_ext($filename) { return strtolower(trim(substr(strrchr($filename, '.'), 1))); } /** * 获取远程文件的header信息 * @param string $url url地址 * @param string $return_type * @return array|bool|string */ function get_remote_file_info($url, $return_type = 'exists') { $head = @get_headers($url, true); $request_status = false; if(is_array($head)) { $t = explode(" ",$head[0]); if(strtoupper($t[count($t)-1]) == "OK") { $request_status = true; } } if ($request_status) { if ($return_type == 'exists') { return $request_status; } elseif ($return_type == 'size') { return trim($head['Content-Length']); //单位bytes 字节 } elseif ($return_type == 'type') { return trim($head['Content-Type']); } else { return $head; } } else { return false; } } function get_url_by_name($file_name) { $url = $file_name; $name = basename($file_name); $serverNo = substr($name, 0, 3); $conf = config('image_servers'); if (isset($conf['servers'][$serverNo]['base_url'])) { $url = rtrim($conf['servers'][$serverNo]['base_url'], '/') . $file_name; } return $url; } /** * 凯撒对称加密核心算法 * @param string $str 字符串源 * @param string $type 类型,encode=加密,decode=解密 * @param string $scale 范围, c=中文, l=字母, n=数字,多种用半角逗号分隔开 * @param int $offset 偏移 * @return string */ function caesar_cipher($str, $type = 'encode', $scale = 'c,l,n', $offset = 3) { if (empty($str)) { return ''; } if (!$offset) { // 无偏移, 直接返回原来的字符串 return $str; } if (empty($scale)) { $scale = 'c,l,n'; } if ($type == 'decode') { // 解密反向偏移 $offset = -$offset; } $func = function ($match, $offset, $start, $end) { $min = ord($start); $max = ord($end); $flag_old = ord($match); $flag = $flag_old + $offset; if ($offset > 0) { if ($flag > $max) { $flag -= ($max - $min) + 1; } } elseif ($offset < 0) { if ($flag < $min) { $flag += ($max - $min) + 1; } } return chr($flag); }; $arr_scale = explode(',', $scale); //允许的范围转换成数组,方便判断 $pattern = '/[\x{4e00}-\x{9fbb}a-zA-Z0-9]/u'; $result = preg_replace_callback( $pattern, function ($matches) use ($offset, $arr_scale, $func) { $str = $match = $matches[0]; if (preg_match('/[\x{4e00}-\x{9fbb}]/u', $match)) { // 汉字 if (in_array('c', $arr_scale)) { $min = intval(hexdec(unpack("H6codes", "一")['codes'])); $max = intval(hexdec(unpack("H6codes", "龻")['codes'])); $arr_hex = unpack("H6codes", $match); $zi_hex = $arr_hex['codes']; $zi_dec = intval(hexdec($zi_hex)); $flag = $zi_dec + $offset; if ($offset > 0) { if ($flag > $max) { $flag -= ($max - $min) + 1; } } elseif ($offset < 0) { if ($flag < $min) { $flag += ($max - $min) + 1; } } $str_hex = dechex($flag); $str = pack("H". strlen($str_hex), $str_hex); } } elseif (preg_match('/[0-9]/', $match)) { // 数字 if (in_array('n', $arr_scale)) { $str = $func($match, $offset, '0', '9'); } } elseif (preg_match('/[a-z]/', $match)) { // 小写字母 if (in_array('l', $arr_scale)) { $str = $func($match, $offset, 'a', 'z'); } } elseif (preg_match('/[A-Z]/', $match)) { // 大写字母 if (in_array('l', $arr_scale)) { $str = $func($match, $offset, 'A', 'Z'); } } return $str; }, $str ); return $result; } /** * 凯撒对称加密 * @param string $str 字符串源 * @param string $scale 范围, c=中文, l=字母, n=数字,多种用半角逗号分隔开 * @param int $offset 偏移 * @return string */ function caesar_encode($str, $scale = 'c,l,n', $offset = 3) { return caesar_cipher($str, 'encode', $scale, $offset); } /** * 凯撒对称解密 * @param string $str 字符串源 * @param string $scale 范围, c=中文, l=字母, n=数字,多种用半角逗号分隔开 * @param int $offset 偏移 * @return string */ function caesar_decode($str, $scale = 'c,l,n', $offset = 3) { return caesar_cipher($str, 'decode', $scale, $offset); } /** * 文件hash md5,大文件针对前10M数据. * @var $filePath string 文件路径 * @var $maxSize int 部分hash的尺寸,单位字节 * @return string */ function hash_md5_file($filePath, $maxSize = 10485760) { $fileSize = filesize($filePath); $md5fileMaxSize = 60 * 1024 * 1024; if ($fileSize <= $md5fileMaxSize) { return md5_file($filePath); } else { $chunkSize = 65536; $size = $maxSize; $fp = fopen($filePath, 'r'); $cxt = hash_init('md5'); // 初始化. while ($size > 0) { $buffer = fread($fp, min($size, $chunkSize)); hash_update($cxt, $buffer); $size -= $chunkSize; } $hash = hash_final($cxt); fclose($fp); // 记得释放文件. return $hash; } } /** * 转换至mongoISODate格式. * @param mixed $date 任意有效的时间格式. * @param mixed $tz 时区 * @return \MongoDB\BSON\UTCDateTime */ function toMongoIsoDate($date, $tz = null) { if (empty($tz)) { $tz = env('APP_TIMEZONE', null); } $millSecond = \Carbon\Carbon::parse($date)->timestamp * 1000; $isoDateObj = new MongoDB\BSON\UTCDateTime($millSecond); $isoDate = $isoDateObj->toDateTime()->setTimezone(new DateTimeZone($tz)); return $isoDateObj; } /** * 修正东8区时间 * * @param $date * @return false|string */ function timeCorrection($date) { return date("Y-m-d H:i:s", strtotime($date . ' -8 hour')); } /** * mongoIso时间转CarbonTime时间 * @param \MongoDB\BSON\UTCDateTime $utcDate * @return \Carbon\Carbon */ function mongoIsoDateToCarbonTime(\MongoDB\BSON\UTCDateTime $utcDate) { return \Carbon\Carbon::parse($utcDate->toDateTime()->setTimezone(new DateTimeZone(env('APP_TIMEZONE')))); }