// +---------------------------------------------------------------------- declare (strict_types=1); /** * 应用公共函数库文件 */ use think\Response; use think\facade\Env; use think\facade\Log; use think\facade\Config; use think\facade\Request; use app\common\library\helper; use app\common\exception\BaseException; use think\exception\HttpResponseException; /** * 打印调试函数 * @param $content * @param bool $isDie * @param bool $export */ function pre($content, bool $isDie = true, bool $export = false) { header('Content-type: text/html; charset=utf-8'); $output = $export ? var_export($content, true) : print_r($content, true); echo "
{$output}";
$isDie && die;
}
/**
* 规则:生成随机数,最多14位数字
* @return string
*/
function random_num($len = 9)
{
return substr(implode(NULL, array_map('ord', str_split(substr(uniqid(), 7, 13), 1))), 0, 9);
}
/**
* 规则:生成随机字符
* @return string
*/
function random_character($len = 8)
{
$arr = array_merge(range(0,9),range('a','z'),range('A','Z'));
$str = '';
for ($i=0;$i<$len;$i++){
$str .= $arr[rand(0,count($arr)-1)];
}
return $str;
}
/**
* 输出错误信息
* @param string $message 报错信息
* @param int|null $status 状态码,默认为配置文件status.error
* @param array $data 附加数据
* @throws BaseException
*/
function throwError(string $message, $status = null, array $data = [])
{
is_null($status) && $status = config('status.error');
throw new BaseException(['status' => $status, 'msg' => $message, 'data' => $data]);
}
/**
* 下划线转驼峰
* @param $uncamelized_words
* @param string $separator
* @return string
*/
function camelize($uncamelized_words, $separator = '_')
{
$uncamelized_words = $separator . str_replace($separator, " ", strtolower($uncamelized_words));
return ltrim(str_replace(" ", "", ucwords($uncamelized_words)), $separator);
}
/**
* 驼峰转下划线
* @param $camelCaps
* @param string $separator
* @return string
*/
function uncamelize($camelCaps, $separator = '_')
{
return strtolower(preg_replace('/([a-z])([A-Z])/', "$1" . $separator . "$2", $camelCaps));
}
/**
* 生成密码hash值
* @param $password
* @return string
*/
function encryption_hash($password)
{
return password_hash($password, PASSWORD_DEFAULT);
}
/**
* 获取当前域名及根路径
* @return string
*/
function base_url()
{
static $baseUrl = '';
if (empty($baseUrl)) {
$request = Request::instance();
// url协议,设置强制https或自动获取
$scheme = Config::get('route')['url_force_https'] ? 'https' : $request->scheme();
// url子目录
$rootUrl = root_url();
// 拼接完整url
$baseUrl = "{$scheme}://" . $request->host() . $rootUrl;
}
return $baseUrl;
}
/**
* 获取当前uploads目录访问地址
* @return string
*/
function uploads_url()
{
return base_url() . 'uploads';
}
/**
* 获取当前url的子目录路径
* @return string
*/
function root_url()
{
static $rootUrl = '';
if (empty($rootUrl)) {
$request = Request::instance();
$subUrl = str_replace('\\', '/', dirname($request->baseFile()));
$rootUrl = $subUrl . ($subUrl === '/' ? '' : '/');
}
return $rootUrl;
}
/**
* 获取当前的应用名称
* @return mixed
*/
function app_name()
{
return app('http')->getName();
}
/**
* 获取web根目录
* @return string
*/
function web_path()
{
static $webPath = '';
if (empty($webPath)) {
$request = Request::instance();
$webPath = dirname($request->server('SCRIPT_FILENAME')) . DIRECTORY_SEPARATOR;
}
return $webPath;
}
/**
* 获取runtime根目录路径
* @return string
*/
function runtime_root_path()
{
return dirname(runtime_path()) . DIRECTORY_SEPARATOR;
}
/**
* 写入日志 (使用tp自带驱动记录到runtime目录中)
* @param $value
* @param string $type
*/
function log_record($value, $type = 'info')
{
$content = is_string($value) ? $value : print_r($value, true);
Log::record($content, $type);
}
/**
* curl请求指定url (post)
* @param $url
* @param array $data
* @return mixed
*/
function curl_post($url, $data = [])
{
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
/**
* 多维数组合并
* @param $array1
* @param $array2
* @return array
*/
function array_merge_multiple($array1, $array2)
{
$merge = $array1 + $array2;
$data = [];
foreach ($merge as $key => $val) {
if (
isset($array1[$key])
&& is_array($array1[$key])
&& isset($array2[$key])
&& is_array($array2[$key])
) {
$data[$key] = is_assoc($array1[$key]) ? array_merge_multiple($array1[$key], $array2[$key]) : $array2[$key];
} else {
$data[$key] = isset($array2[$key]) ? $array2[$key] : $array1[$key];
}
}
return $data;
}
/**
* 判断是否为自定义索引数组
* @param array $array
* @return bool
*/
function is_assoc(array $array)
{
if (empty($array)) return false;
return array_keys($array) !== range(0, count($array) - 1);
}
/**
* 二维数组排序
* @param $arr
* @param $keys
* @param bool $desc
* @return mixed
*/
function array_sort($arr, $keys, $desc = false)
{
$key_value = $new_array = array();
foreach ($arr as $k => $v) {
$key_value[$k] = $v[$keys];
}
if ($desc) {
arsort($key_value);
} else {
asort($key_value);
}
reset($key_value);
foreach ($key_value as $k => $v) {
$new_array[$k] = $arr[$k];
}
return $new_array;
}
/**
* 隐藏敏感字符
* @param $value
* @return string
*/
function substr_cut($value)
{
$strlen = mb_strlen($value, 'utf-8');
if ($strlen <= 1) return $value;
$firstStr = mb_substr($value, 0, 1, 'utf-8');
$lastStr = mb_substr($value, -1, 1, 'utf-8');
return $strlen == 2 ? $firstStr . str_repeat('*', $strlen - 1) : $firstStr . str_repeat("*", $strlen - 2) . $lastStr;
}
/**
* 获取当前系统版本号
* @return mixed|null
* @throws Exception
*/
function get_version()
{
static $version = [];
if (!empty($version)) {
return $version['version'];
}
// 读取version.json文件
$file = root_path() . '/version.json';
if (!file_exists($file)) {
throw new Exception('version.json not found');
}
// 解析json数据
$version = helper::jsonDecode(file_get_contents($file));
if (!is_array($version)) {
throw new Exception('version cannot be decoded');
}
return $version['version'];
}
/**
* 获取全局唯一标识符
* @param bool $trim
* @return string
*/
function get_guid_v4($trim = true)
{
// Windows
if (function_exists('com_create_guid') === true) {
$charid = com_create_guid();
return $trim == true ? trim($charid, '{}') : $charid;
}
// OSX/Linux
if (function_exists('openssl_random_pseudo_bytes') === true) {
$data = openssl_random_pseudo_bytes(16);
$data[6] = chr(ord($data[6]) & 0x0f | 0x40); // set version to 0100
$data[8] = chr(ord($data[8]) & 0x3f | 0x80); // set bits 6-7 to 10
return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
}
// Fallback (PHP 4.2+)
mt_srand(intval((double)microtime() * 10000));
$charid = strtolower(md5(uniqid((string)rand(), true)));
$hyphen = chr(45); // "-"
$lbrace = $trim ? "" : chr(123); // "{"
$rbrace = $trim ? "" : chr(125); // "}"
return $lbrace .
substr($charid, 0, 8) . $hyphen .
substr($charid, 8, 4) . $hyphen .
substr($charid, 12, 4) . $hyphen .
substr($charid, 16, 4) . $hyphen .
substr($charid, 20, 12) .
$rbrace;
}
/**
* 时间戳转换日期
* @param $timeStamp
* @return false|string
*/
function format_time($timeStamp)
{
return $timeStamp>0?date('Y-m-d H:i:s', $timeStamp):'';
}
/**
* 左侧填充0
* @param $value
* @param int $padLength
* @return string
*/
function pad_left($value, $padLength = 2)
{
return \str_pad($value, $padLength, "0", STR_PAD_LEFT);
}
/**
* 重写trim方法 (解决int类型过滤后后变为string类型)
* @param $str
* @return string
*/
function my_trim($str)
{
return is_string($str) ? trim($str) : $str;
}
/**
* 重写htmlspecialchars方法 (解决int类型过滤后后变为string类型)
* @param $string
* @return string
*/
function my_htmlspecialchars($string)
{
return is_string($string) ? htmlspecialchars($string) : $string;
}
/**
* 过滤emoji表情
* @param $text
* @return null|string|string[]
*/
function filter_emoji($text)
{
if (!is_string($text)) {
return $text;
}
// 此处的preg_replace用于过滤emoji表情
// 如需支持emoji表情, 需将mysql的编码改为utf8mb4
return preg_replace('/[\xf0-\xf7].{3}/', '', $text);
}
/**
* 根据指定长度截取字符串
* @param $str
* @param int $length
* @return bool|string
*/
function str_substr($str, $length = 30)
{
if (strlen($str) > $length) {
$str = mb_substr($str, 0, $length);
}
return $str;
}
/**
* 结束执行
*/
function app_end()
{
throw new HttpResponseException(Response::create());
}
/**
* 当前是否为调试模式
* @return bool
*/
function is_debug()
{
return (bool)Env::instance()->get('APP_DEBUG');
}
/**
* 文本左斜杠转换为右斜杠
* @param $string
* @return mixed
*/
function convert_left_slash(string $string)
{
return str_replace('\\', '/', $string);
}
/**
* 隐藏手机号中间四位 13012345678 -> 130****5678
* @param string $mobile 手机号
* @return string
*/
function hide_mobile(string $mobile)
{
return substr_replace($mobile, '****', 3, 4);
}
/**
* 隐藏手机号中间四位 42102200201019999 -> 4210************999
* @param string $idcard 手机号
* @return string
*/
function hide_id_card(string $idcard)
{
return substr_replace($idcard, '***********', 4, 11);
}
/**
* 生成用户昵称
*/
function make_nickname(string $mobile)
{
return '用户' . substr($mobile, -4);
}
/**
* 获取当前登录的商城ID
* @return int $storeId
*/
function getStoreId()
{
return 10001;
}
/**
* 获取缩短后的字符串
* @return string
*/
function limit_str(string $str,int $limit=6)
{
if(mb_strlen($str)<$limit){
return $str;
}else{
return mb_substr(strip_tags($str),0,$limit,'UTF-8')."...";
}
}
/**
* 获取指定范围的所有日期
*
* @param int $start
* @param int $end
* @param string $format
* @return array
*/
function period_date($start, $end, $format = 'Y-m-d')
{
$arr = [];
while ($start <= $end) {
$arr[] = date($format, $start);
$start = strtotime('+1 day', $start);
}
return $arr;
}
/**
* 获取指定范围的所有周
*
* @param int $start
* @param int $end
* @param boolean 是否过滤不满一周的数据
*
* @return array
*/
function period_week($start, $end, $filter = false)
{
//开始时间
$startDate = date('Y-m-d', $start);
//结束时间
if (empty($end)) {
$endDate = date('Y-m-d');
} else {
$endDate = date('Y-m-d', $end);
}
//跨越天数
$n = (strtotime($endDate) - strtotime($startDate)) / 86400;
//判断,跨度小于7天,可能是同一周,也可能是两周
$endDate = date("Y-m-d", strtotime("$endDate +1 day"));
if ($n < 7) {
//查开始时间 在 那周 的 位置
$day = date("w", strtotime($startDate)) - 1;
//查开始时间 那周 的 周一
$week_start = date("Y-m-d", strtotime("$startDate -{$day} day"));
//查开始时间 那周 的 周末
$day = 7 - $day;
$week_end = date("Y-m-d", strtotime("$startDate +{$day} day"));
//判断周末时间是否大于时间段的结束时间,如果大于,那就是时间段在同一周,否则时间段跨两周
if ($week_end >= $endDate) {
$weekList[] = array('s' => $startDate, 'e' => date("Y-m-d", strtotime("$endDate -1 day")));
} else {
$weekList[] = array('s' => $startDate, 'e' => date("Y-m-d", strtotime("$week_end -1 day")));
$weekList[] = array('s' => $week_end, 'e' => date("Y-m-d", strtotime("$endDate -1 day")));
}
} else {
//如果跨度大于等于7天,可能是刚好1周或跨2周或跨N周,先找出开始时间 在 那周 的 位置和那周的周末时间
$day = date("w", strtotime($startDate)) - 1;
$week_start = date("Y-m-d", strtotime("$startDate -{$day} day"));
$day = 7 - $day;
$week_end = date("Y-m-d", strtotime("$startDate +{$day} day"));
//先把开始时间那周写入数组
$weekList[] = array('s' => $startDate, 'e' => date("Y-m-d", strtotime("$week_end -1 day")));
//判断周末是否大于等于结束时间,不管大于(2周)还是等于(1周),结束时间都是时间段的结束时间。
if ($week_end >= $endDate) {
$weekList[] = array('s' => $week_end, 'e' => date("Y-m-d", strtotime("$endDate -1 day")));
} else {
//N周的情况用while循环一下,然后写入数组
while ($week_end <= $endDate) {
$start = $week_end;
$week_end = date("Y-m-d", strtotime("$week_end +7 day"));
if ($week_end <= $endDate) {
$weekList[] = array('s' => $start, 'e' => date("Y-m-d", strtotime("$week_end -1 day")));
} else {
// 如果当前时间是每周第一天
if ($start == $endDate) {
$weekList[] = array('s' => $start, 'e' => date("Y-m-d", strtotime("$endDate 0 day")));
} else {
$weekList[] = array('s' => $start, 'e' => date("Y-m-d", strtotime("$endDate -1 day")));
}
}
}
}
}
// 过滤不满一周天数的数据
$firstWeek = current($weekList);
$lastWeek = end($weekList);
$firstWeekDays = (strtotime($firstWeek['e']) - strtotime($firstWeek['s'])) / 86400;
$lastWeekDays = (strtotime($lastWeek['e']) - strtotime($lastWeek['s'])) / 86400;
if ($firstWeekDays < 7 && $filter) {
array_shift($weekList);
}
if ($lastWeekDays < 7 && $filter) {
array_pop($weekList);
}
return $weekList;
}
/**
* 生成从开始月份到结束月份的月份数组
* @param int $start 开始时间戳
* @param int $end 结束时间戳
* @param boolean 是否过滤当前月等于最后一个月的数据
*/
function period_month($start, $end, $filter = false)
{
if (!is_numeric($start) || !is_numeric($end) || ($end <= $start)) return '';
$start = date('Y-m', $start);
$end = date('Y-m', $end);
//转为时间戳
$start = strtotime($start . '-01');
$end = strtotime($end . '-01');
$i = 0;
$d = array();
while ($start <= $end) {
//这里累加每个月的的总秒数 计算公式:上一月1号的时间戳秒数减去当前月的时间戳秒数
$d[$i] = trim(date('Y-m', $start), ' ');
$start += strtotime('+1 month', $start) - $start;
$i++;
}
if (end($d) == date('Y-m') && $filter) {
array_pop($d);
}
return $d;
}
function month_first_last($date)
{
$firstday = date('Y-m-01', strtotime($date));
$lastday = date('Y-m-d', strtotime("$firstday +1 month -1 day"));
return ['s' => $firstday, 'e'=>$lastday];
}
/**
* 获取上月月份
* @param int $days 默认上个月
* @return false|string
*/
function last_month($format = "Y-m", $days = 1, $time = 0)
{
if (!$time) {
$time = time();
}
return date($format, strtotime(date('Y-m-01') . " -{$days} month", $time));
}
function last_week_between_time()
{
$s = mktime(0,0,0,(int)date('m'),(int)(date('d')-date('w')+1-7),(int)date('Y'));
$e = mktime(23,59,59,(int)date('m'),(int)(date('d')-date('w')+7-7),(int)date('Y'));
return ['s' => $s, 'e'=>$e];
}
/*
POST
*/
function post_curl($posturl, $params, $method = 'POST', $header = '') {
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $posturl);
if ($header)
curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
switch ($method) {
case 'GET':
curl_setopt($curl, CURLOPT_HTTPGET, 1);
case 'POST':
curl_setopt($curl, CURLOPT_POST, 1);
break;
case 'PUT':
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
break;
case 'DELETE':
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
break;
}
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, False);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($curl, CURLOPT_HEADER, FALSE);
curl_setopt($curl, CURLOPT_POSTFIELDS, $params);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$retdata = curl_exec($curl);
curl_close($curl);
return $retdata;
}