0 && !isset($item["folder"])) { $item["folder"] = true; } $return[] = $item; } } return $return; } /** * tree 转一维数组 * @param $array * @return array */ function flatten_tree($array, $key = "children") { $result = []; foreach ($array as $item) { $result[] = $item; if (count($item[$key]) > 0) { $result = array_merge($result, flatten_tree($item[$key], $key)); } } return $result; } /** * 根据pid找寻所有的上层节点 * @param $array * @param $val * @param string $parent_key * @param array $result * @return array */ function get_pid($array, $val, $parent_key = "pid", $result = []) { $array = array_by_key($array, "id"); if (!isset($array[$val])) { return $result; } if ($array[$val][$parent_key] == 0 || !isset($array[$array[$val][$parent_key]])) { return $result; } else { $result[] = $array[$val][$parent_key]; return get_pid($array, $array[$val][$parent_key], $parent_key, $result); } } /** * 根据平行数组递归查找子节点 * @param $array * @param $key * @param $parent_key * @param $val * @param array $return * @return array */ function find_children($array, $key, $parent_key, $val, $return = []) { foreach ($array as $item) { if ($item[$parent_key] == $val) { $return[] = $item; $return = find_children($array, $key, $parent_key, $item[$key], $return); } } return $return; } /** * 18位身份证转年龄 * @param $IDnumber * @return bool|string */ function id_number2age($IDnumber) { $year = (int)substr($IDnumber, 6, 4); return date("Y") - $year; } /** * * @param $num * @param $lower * @return float|int|mixed|string */ function number2chinese($num, $lower = false) { $c1 = "零壹贰叁肆伍陆柒捌玖"; $c2 = "分角元拾佰仟万拾佰仟亿"; if ($lower) { $c1 = "零一二三四五六七八九"; $c2 = "分角元十佰仟万拾佰仟亿"; } $num = round($num, 2); $num = $num * 100; if (strlen($num) > 11) { return $num; } $i = 0; $c = ""; while (1) { if ($i == 0) { $n = substr($num, strlen($num) - 1, 1); } else { $n = $num % 10; } $p1 = substr($c1, 3 * $n, 3); $p2 = substr($c2, 3 * $i, 3); if ($n != '0' || ($n == '0' && ($p2 == '亿' || $p2 == '万' || $p2 == '元'))) { $c = $p1 . $p2 . $c; } else { $c = $p1 . $c; } $i = $i + 1; $num = $num / 10; $num = (int)$num; if ($num == 0) { break; } } $j = 0; $slen = strlen($c); while ($j < $slen) { $m = substr($c, $j, 6); if ($m == '零元' || $m == '零万' || $m == '零亿' || $m == '零零') { $left = substr($c, 0, $j); $right = substr($c, $j + 3); $c = $left . $right; $j = $j - 3; $slen = $slen - 3; } $j = $j + 3; } if (substr($c, strlen($c) - 3, 3) == '零') { $c = substr($c, 0, strlen($c) - 3); } if (empty($c)) { return "零"; } else { return str_replace("元", "", $c); } } /** * 替换字符串中的部分字符串为星号 * @param null $string * @return string|null */ function string2secret($string = NULL) { if (!$string) { return NULL; } $length = mb_strlen($string); $visibleCount = (int)round($length / 4); $hiddenCount = $length - ($visibleCount * 2); return mb_substr($string, 0, $visibleCount) . str_repeat('*', $hiddenCount) . mb_substr($string, ($visibleCount * -1), $visibleCount); } /** * 友好的时间显示 * * @param int $sTime 待显示的时间 * @param string $type 类型. normal | mohu | full | ymd | other * @param string $alt 已失效 * @return string */ function friendly_date($sTime, $type = 'normal', $alt = 'false') { if (!$sTime) return ''; //sTime=源时间,cTime=当前时间,dTime=时间差 $sTime = strtotime($sTime); $cTime = time(); $dTime = $cTime - $sTime; $after_or_before = "前"; $dDay = intval(date("z", $cTime)) - intval(date("z", $sTime)); $dYear = intval(date("Y", $cTime)) - intval(date("Y", $sTime)); if ($sTime > $cTime) { $dTime = $sTime - $cTime; $after_or_before = "后"; $dDay = intval(date("z", $sTime)) - intval(date("z", $cTime)); $dYear = intval(date("Y", $sTime)) - intval(date("Y", $cTime)); } //normal:n秒前,n分钟前,n小时前,日期 if ($type == 'normal') { if ($dTime < 60) { if ($dTime < 10) { return '刚刚'; //by yangjs } else { return intval(floor($dTime / 10) * 10) . "秒{$after_or_before}"; } } elseif ($dTime < 3600) { return intval($dTime / 60) . "分钟{$after_or_before}"; //今天的数据.年份相同.日期相同. } elseif ($dYear == 0 && $dDay == 0) { //return intval($dTime/3600)."小时前"; return '今天' . date('H:i', $sTime); } elseif ($dYear == 0) { return date("m月d日 H:i", $sTime); } else { return date("Y-m-d H:i", $sTime); } } elseif ($type == 'mohu') { if ($dTime < 60) { return $dTime . "秒{$after_or_before}"; } elseif ($dTime < 3600) { return intval($dTime / 60) . "分钟{$after_or_before}"; } elseif ($dTime >= 3600 && $dDay == 0) { return intval($dTime / 3600) . "小时{$after_or_before}"; } elseif ($dDay > 0 && $dDay <= 7) { return intval($dDay) . "天{$after_or_before}"; } elseif ($dDay > 7 && $dDay <= 30) { return intval($dDay / 7) . "周{$after_or_before}"; } elseif ($dDay > 30) { return intval($dDay / 30) . "个月{$after_or_before}"; } //full: Y-m-d , H:i:s } elseif ($type == 'full') { return date("Y-m-d , H:i:s", $sTime); } elseif ($type == 'ymd') { return date("Y-m-d", $sTime); } else { if ($dTime < 60) { return $dTime . "秒{$after_or_before}"; } elseif ($dTime < 3600) { return intval($dTime / 60) . "分钟{$after_or_before}"; } elseif ($dTime >= 3600 && $dDay == 0) { return intval($dTime / 3600) . "小时{$after_or_before}"; } elseif ($dYear == 0) { return date("Y-m-d H:i:s", $sTime); } else { return date("Y-m-d H:i:s", $sTime); } } } /** * 多行文本转为radio选项 * @param $text * @param string $value * @param bool $block * @return string */ function multiline2radio($text, $value = "", $block = false) { $res = '
'; $text = explode("\r\n", $text); $block = $block === true ? "d-block" : ""; for ($i = 0; $i < count($text); $i++) { $checked = ""; if ($value === (string)$text[$i]) { $checked = "checked"; } if ((string)$text[$i] == "splitter") { $res .= "
"; } else { $res .= '
'; } } $res .= "
"; return $res; } function multiline2html($text) { $html = str_replace(["\r\n", "\r", "\n"], "
", $text); return $html; } /** * 小时格式字符转秒数 * @param $hour * @return mixed */ function hour2second($hour) { $hour = explode(":", $hour); $second = $hour[0] * 3600 + $hour[1] * 60 + $hour[2]; return $second; } /** * 秒数转小数格式 * @param $second * @return mixed */ function second2hour($second) { $hours = floor($second / 3600); $minutes = floor(($second - $hours * 3600) / 60); $seconds = floor($second - $hours * 3600 - $minutes * 60); return sprintf("%02s", $hours) . ":" . sprintf("%02s", $minutes) . ":" . sprintf("%02s", $seconds); } function curl($url, $post = array(), $arr_return = true) { $curl = curl_init(); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $post); $return_str = curl_exec($curl); curl_close($curl); if ($arr_return) { return json_decode($return_str, true); } else { return $return_str; } } function is_wechat() { return strpos($_SERVER["HTTP_USER_AGENT"], "MicroMessenger"); } function sms($to, $vars, $template_id, $belongs_type = null, $belongs_id = null) { $sms_app_id = env('SMS_APPID'); $sms_app_key = env('SMS_APPKEY'); is_array($vars) ? $vars = json_encode($vars) : ''; $data = "appid=" . $sms_app_id . "&signature=" . $sms_app_key . "&project=" . $template_id . "&vars=" . $vars . "&to=" . $to; $url = "https://api.submail.cn/message/xsend.json"; $return = curl($url, $data); $sms['mobile'] = $to; $sms['vars'] = $vars; $sms['template_id'] = $template_id; $sms['ip'] = request()->getClientIp(); $sms['status'] = $return['status']; $sms['belongs_type'] = $belongs_type; $sms['belongs_id'] = $belongs_id; if ($return['status'] != "success") { $sms['result_code'] = $return['code']; $sms['result_msg'] = $return['msg']; } $sms['created_at'] = date("Y-m-d H:i:s"); (new \App\Models\Sms())->insert($sms); return $return['status'] == "success"; } function get_http_type() { $http_type = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == 'on') || (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https')) ? 'https://' : 'http://'; return $http_type; } /** * 友好的时间显示 * * @param int $sTime 待显示的时间 * @param string $type 类型. normal | mohu | full | ymd | other * @param string $alt 已失效 * @return string */ function friendly_date2($sTime, $cTime = false, $type = 'mohu', $show_after_or_before = false) { if (!$sTime) return ''; //sTime=源时间,cTime=当前时间,dTime=时间差 $sTime = strtotime($sTime); $cTime ? $cTime = strtotime($cTime) : time(); $dTime = $cTime - $sTime; $after_or_before = "前"; $dDay = intval(date("z", $cTime)) - intval(date("z", $sTime)); $dYear = intval(date("Y", $cTime)) - intval(date("Y", $sTime)); if ($sTime > $cTime) { $dTime = $sTime - $cTime; $after_or_before = "后"; $dDay = intval(date("z", $sTime)) - intval(date("z", $cTime)); $dYear = intval(date("Y", $sTime)) - intval(date("Y", $cTime)); } $show_after_or_before ? "" : $after_or_before = ""; //normal:n秒前,n分钟前,n小时前,日期 if ($type == 'normal') { if ($dTime < 60) { if ($dTime < 10) { return '刚刚'; //by yangjs } else { return intval(floor($dTime / 10) * 10) . "秒{$after_or_before}"; } } elseif ($dTime < 3600) { return intval($dTime / 60) . "分钟{$after_or_before}"; //今天的数据.年份相同.日期相同. } elseif ($dYear == 0 && $dDay == 0) { //return intval($dTime/3600)."小时前"; return '今天' . date('H:i', $sTime); } elseif ($dYear == 0) { return date("m月d日 H:i", $sTime); } else { return date("Y-m-d H:i", $sTime); } } elseif ($type == 'mohu') { if ($dTime < 60) { return $dTime . "秒{$after_or_before}"; } elseif ($dTime < 3600) { return intval($dTime / 60) . "分钟{$after_or_before}"; } elseif ($dTime >= 3600 && $dDay == 0) { return intval($dTime / 3600) . "小时{$after_or_before}"; } elseif ($dDay > 0 && $dDay <= 7) { return intval($dDay) . "天{$after_or_before}"; } elseif ($dDay > 7 && $dDay <= 30) { return intval($dDay / 7) . "周{$after_or_before}"; } elseif ($dDay > 30) { return intval($dDay / 30) . "个月{$after_or_before}"; } //full: Y-m-d , H:i:s } elseif ($type == 'full') { return date("Y-m-d , H:i:s", $sTime); } elseif ($type == 'ymd') { return date("Y-m-d", $sTime); } else { if ($dTime < 60) { return $dTime . "秒{$after_or_before}"; } elseif ($dTime < 3600) { return intval($dTime / 60) . "分钟{$after_or_before}"; } elseif ($dTime >= 3600 && $dDay == 0) { return intval($dTime / 3600) . "小时{$after_or_before}"; } elseif ($dYear == 0) { return date("Y-m-d H:i:s", $sTime); } else { return date("Y-m-d H:i:s", $sTime); } } } // 获取当前域名 function getDomain() { return get_http_type() . $_SERVER['HTTP_HOST']; } /** * 获取字段的关联字段输出名字 */ function getFieldWithName($detail) { $array = []; if (isset($detail['local_key'])) $array[] = $detail['local_key']; if (isset($detail['link_table_name'])) $array[] = $detail['link_table_name']; if (isset($detail['foreign_key'])) $array[] = $detail['foreign_key']; $array[] = 'relation'; return implode('_', $array); } /** * 获取编码 */ function getBatchNo() { $microtime = microtime(true); $millisecond = sprintf("%03d", ($microtime - floor($microtime)) * 1000); return date('YmdHis') . $millisecond; } function httpCurl($url, $method = 'GET', $params = [], $header = []) { $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); //将获取的信息以字符串返回,而不是直接输出 curl_setopt($ch, CURLOPT_URL, $method == "POST" ? $url : $url . '?' . http_build_query($params)); //http_build_query数组转Url格式参数 //设置超时时间 curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60); curl_setopt($ch, CURLOPT_TIMEOUT, 60); //如果是https协议,取消检测SSL证书 if (stripos($url, "https://") !== FALSE) { curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); //CURL_SSLVERSION_TLSv1 curl_setopt($ch, CURLOPT_SSLVERSION, 1); } //判断是否设置请求头 if (count($header) >= 1) { curl_setopt($ch, CURLOPT_HTTPHEADER, $header); } //通过POST方式提交 if ($method == "POST") { curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_POSTFIELDS, $params); } $data = curl_exec($ch); //执行curl操作 if ($data === false) { $data = curl_error($ch); } curl_close($ch); //关闭curl操作 return $data; } /** * @param $to * @param $vars * @param $template_id * @param null $belongs_type * @param null $belongs_id * @return bool */ function ymSms($to, $vars = [], $template_id = 0, $belongs_type = null, $belongs_id = null) { $url = "http://www.btom.cn:8080/simpleinter/sendSMS"; $header[] = 'Content-Type: application/json'; $params = [ 'appId' => config('app.sms_appid'), 'timestamp' => date('YmdHis'), 'mobiles' => $to, 'content' => $vars, ]; $params['sign'] = md5(config('app.sms_appid') . config('app.sms_secretKey') . $params['timestamp']); $return = httpCurl($url, 'GET', $params, $header); $return = json_decode($return, true); $sms['mobile'] = $to; $sms['vars'] = $vars; $sms['template_id'] = $template_id; $sms['ip'] = request()->getClientIp(); $sms['status'] = $return['code']; $sms['belongs_type'] = $belongs_type; $sms['belongs_id'] = $belongs_id; if ($return['code'] != "SUCCESS") { $sms['result_code'] = $return['code']; $sms['result_msg'] = '发送失败'; } $sms['created_at'] = date("Y-m-d H:i:s"); (new \App\Models\Sms())->insert($sms); return $return['code'] == "SUCCESS"; } // 驼峰法命名转下划线命名 function underlineToHump($array) { $ay = []; foreach ($array as $item) { $ay[] = Str::camel($item); } return $ay; } /** * 根据身份证号识别性别 * @param $cid * @return string 0未知 1男 2女 */ function idCardToSex($idcard) { //根据身份证号返回性别 if (empty($idcard) || !isIdCard($idcard)) { return '男'; } $sexint = (int)substr($idcard, 16, 1); return $sexint % 2 === 0 ? '女' : '男'; } /** * 判断是否身份号码 * @param $number * @return bool */ function isIdCard($idCard) { if (strlen($idCard) != 18) { return false; } # 转化为大写,如出现x $idcard = strtoupper($idCard); # 加权因子 $wi = array(7, 9, 10, 5, 8, 4, 2, 1, 6, 3, 7, 9, 10, 5, 8, 4, 2); $ai = array('1', '0', 'X', '9', '8', '7', '6', '5', '4', '3', '2'); # 按顺序循环处理前17位 $sigma = 0; # 提取前17位的其中一位,并将变量类型转为实数 for ($i = 0; $i < 17; $i++) { $b = (int)$idcard[$i]; # 提取相应的加权因子 $w = $wi[$i]; # 把从身份证号码中提取的一位数字和加权因子相乘,并累加 $sigma += $b * $w; } # 计算序号 $sidcard = $sigma % 11; # 按照序号从校验码串中提取相应的字符。 $check_idcard = $ai[$sidcard]; if ($idcard[17] == $check_idcard) { return true; } else { return false; } } /** * 判断数组是否二维数组 * @param $array * @return bool */ function isMultiDimensionalArray($array) { return is_array($array) && count(array_filter($array, 'is_array')) > 0; } /** * 求两个已知经纬度之间的距离,单位为km * @param lat1,lat2 纬度 * @param lng1,lng2 经度 * @return float 距离,单位为km **/ function getDistance($lat1, $lng1, $lat2, $lng2) { //将角度转为狐度 $radLat1 = deg2rad($lat1);//deg2rad()函数将角度转换为弧度 $radLat2 = deg2rad($lat2); $radLng1 = deg2rad($lng1); $radLng2 = deg2rad($lng2); $a = $radLat1 - $radLat2; $b = $radLng1 - $radLng2; $s = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2))) * 6371; return round($s, 1); } /** * 提取中括号里的数据 */ function getVar($text) { $pattern = '/\{.*?\}/'; preg_match_all($pattern, $text, $matches); if (count($matches[0]) > 0) { // 数组转英文逗号分割的字符串 return implode(',', $matches[0]); } return ''; } /** * 获取两个日期之间的所有日期 */ function getDates($start, $end) { $dt_start = strtotime($start); $dt_end = strtotime($end); $temp = []; while ($dt_start <= $dt_end) { $re = date('Y-m-d', $dt_start); $temp[] = $re; $dt_start = strtotime('+1 day', $dt_start); } return $temp; // 返回data型数据 } /** * 将JSON字符串或数组的键值对组合成"键:值,键:值"格式的字符串 * * @param string|array $data 可以是JSON字符串或关联数组 * @return string 组合后的字符串 */ function combineKeyValue($data) { // 如果输入是JSON字符串,则解析为数组 if (is_string($data)) { $data = json_decode($data, true); } // 验证是否为数组 if (!is_array($data)) { return ''; } // 拼接键值对 $parts = []; foreach ($data as $key => $value) { $parts[] = "{$value}"; } // 用逗号连接 return implode(',', $parts); }