TP5 常用的公共函数(长期更新)

以下都是使用tp5框架,本人封装的常用方法

1、数组系列

1.1、二维数组根据pid生成多维树 (注意:父级必须排在数组前面,降维的生成树方法)
/**
 * 二维数组根据pid生成多维树
 * @param $list 父子级拼接数组传入
 * @param $pid 父级ID字段
 * @param $child 子集
 * @return array
 */
function listToTree($list, $pid = 'pid', $child = 'children')
{
    $tree = array();// 创建Tree
    if (is_array($list)) {
        // 创建基于主键的数组引用
        $refer = array();
        foreach ($list as $key => $data) $refer[$data['id']] = &$list[$key];

        foreach ($list as $key => $data) {
            // 判断是否存在parent
            $parentId = $data[$pid];

            if (0 == $parentId) {
                $tree[] = &$list[$key];
                if(isset($list[$key][$child]) && !$list[$key][$child]){
                    $list[$key][$child] = [];
                }
            } else {
                if (isset($refer[$parentId])) {
                    $parent = &$refer[$parentId];
                    $parent[$child][] = &$list[$key];
                }
            }
        }
    }
    return $tree;
}
1.2、根据相关键值生成父子关系(二维生成树)
/**
 * 根据相关键值生成父子关系
 * @param array $arr1 数组1
 * @param array $arr2 数组2
 * @param string $arr1_key 数组1对应的键值
 * @param string $arr2_key 数组2对应的父级键值
 * @param string $child 合并的数组键值
 */
function listToTree2(&$arr1, $arr2, $arr1_key = 'id', $arr2_key = 'pid', $child = 'children')
{
    foreach ($arr1 as $i => &$item1) {
        foreach ($arr2 as $j => $item2) {
            if ($item1[$arr1_key] == $item2[$arr2_key]) {
                if (!isset($item1[$child]) || !is_array($item1[$child])) $item1[$child] = [];
                $item1[$child][] = $item2;
            }
        }
    }
}
1.3、二维数组根据键值排序
/**
 * 二维数组根据键值排序
 * @param array $array 要排序的数组
 * @param string $keys 要用来排序的键名
 * @param string $type 默认为降序排序
 * @return array
 */
function arraySort($array, $keys, $type = 'desc')
{
    //将排序的键名作为键值
    $keysValue = $newArray = [];
    foreach ($array as $k => $v) $keysValue[$k] = $v[$keys];

    ($type == 'asc' || $type == 'ASC') ? asort($keysValue) : arsort($keysValue);
    reset($keysValue); //重置指针

    foreach ($keysValue as $k => $v) $newArray[$k] = $array[$k];

    return array_values($newArray); //重置键值
}
1.4、一维/二维数组根据关键字对数组字段进行相似度排序
/**
 * 一维/二维数组根据关键字对数组字段进行相似度排序
 * @param array $array 原数组
 * @param string $keyword 关键字
 * @param string $field 要匹配的数组字段名,不传则表示一维数组
 * @param int $limit 限制次数,-1不限制
 * @return  array    排序好的数组
 */
function similarArrSort(array $array, string $keyword, $field = '', $limit = -1)
{
    //数组key小于3,直接返回,不符合排序要求(特例,可不写)
    if (count($array) <= 3 || ($limit != -1 && $limit <= 3)) {
        return $array;
    }

    $newField = $field; //赋值

    //如果传入的field为空则表示一维数组,生成field为label的二维数组
    if ($field == '') {
        $label2 = [];
        foreach ($array as $k => $value) $label2[$k]['label'] = $value;
        $array = $label2;
        $newField = 'label';
    }

    //数组相似度处理
    foreach ($array as $key => $value) {
        similar_text($value[$newField], $keyword, $percent);

        $value['percent'] = $percent;
        $data[] = $value;

    }

    //取出数组中percent的一列,返回一维数组
    $percent = array_column($data, 'percent');

    //排序,根据 percent 排序
    array_multisort($percent, SORT_DESC, $data);

    //一维数组处理返回一维数组
    if ($field == '') {
        $newData = [];
        foreach ($data as $k => $v) $newData[$k] = $v[$newField];
        $data = $newData;
    }

    //限制返回数量
    if ($limit != -1) {
        $data = array_slice($data, 0, $limit);
    }

    return $data;
}
1.5、二维数组去重(支持多字段同时匹配去重)
function moreArrayUnique($arr, $field = [], $allField = true)
{
    //必须是传入数组
    if (!is_array($field)) return false;

    //先把二维数组中的内层数组的键值记录在在一维数组中
    foreach ($arr[0] as $k => $v) $allField[] = $k;
    if ($field) {
        //按照顺序排字段名
        foreach ($allField as $key => $val) {
            if (!in_array($val, $field)) unset($allField[$key]);
        }
        $field = $allField;
    }

    foreach ($arr as $k => $v) {
        foreach ($v as $key => $item) {
            if (!in_array($key, $field)) unset($v[$key]);
        }
        //降维 用implode()也行
        $v = implode(",", $v);
        //保留原来的键值 $temp[]即为不保留原来键值
        $temp[$k] = $v;
    }

    //去重:去掉重复的元素
    $arr = array_unique($temp);
    if ($allField) {
        foreach ($arr as $k => $v) {
            //拆分后的重组 如:Array( [0] => 张三 [1] => 18 )
            $a = explode(",", $v);
            //将原来的键与值重新合并
            $arrAfter[] = array_combine($field, $a);
        }

    } else {
        //将键值保存为一维数组
        $allKey = array_keys($temp);
        $arrAfter = [];
        foreach ($arr as $k => $v) {
            //数组去重
            if (!in_array($k, $allKey)) {
                unset($arr[$k]);
            } else {
                $a = explode(",", $v);
                $arrAfter[] = array_combine($field, $a);
            }
        }
    }

    return $arrAfter ?? false;
}
1.6、一层遍历实现2个二维数组的合并
$arr1 = [
    'a'=>[1],
    'b'=>[2],
];
$arr2= [
    'a'=>[4],
    'b'=>[51],
    'c'=>[111]
];
$key1 = array_keys($arr1);
$key2 = array_keys($arr2);
$key = array_unique(array_merge($key1,$key2));
$arr = [];
foreach($key as $k => $v){
    if(isset($arr1[$v]) && isset($arr2[$v])){
        $arr[$v] = array_merge($arr1[$v],$arr2[$v]);
    }else if (isset($arr1[$v])){
        $arr[$v] = $arr1[$v];
    }else if(isset($arr2[$v])){
        $arr[$v] = $arr2[$v];
    }
}

var_dump($arr);
1.7、自定义分页效果
/**
 * 将多维数组继续分页,自定义分页效果
 * @param array &$array 数组
 * @param int $page 当前页数
 * @param int $limit 每页页数
 * @param int $order 0-不变 1-反序
 * @param bool $preserveKey true - 保留键名  false - 默认。重置键名
 */
function arrayToPage(Array &$array, int $page = 1, int $limit = 20, int $order = 0,bool $preserveKey = false)
{
    $start = ($page - 1) * $limit; //计算每次分页的开始位置

    //反序
    if ($order == 1) $array = array_reverse($array);

    $array = array_slice($array, $start, $limit,$preserveKey);
}

2、时间类

2.1、将时间戳转换成多久之前
/**
 * 时间戳转换
 * @param $time
 * @return string
 */
function timeToBefore(int $time)
{
    $t = time() - $time;
    $f = array(
        '31536000' => '年',
        '2592000' => '个月',
        '604800' => '星期',
        '86400' => '天',
        '3600' => '小时',
        '60' => '分钟',
        '1' => '秒'
    );
    foreach ($f as $k => $v) {
        if (0 != $c = floor($t / (int)$k)) {
            return $c . $v . '前';
        }
    }
}
2.2、获取上周/这周7天时间
/**
 * 获取上周的时间数组
 * @param $day 获取当前周的第几天 周日是 0 周一到周六是1-6  
 * @param $format 日期格式
 * @param $last 是否获取上周,1=上周7天,0=这周7天
 * @return array
 */
function getWeekDayArr(int $day, string $format = 'Ymd', int $last = 1)
{
    if ($last == 1) {
        //获取本周开始日期,如果$day是0是周日:-6天;其它:$day-1天  
        $beginLastweek = strtotime(date($format) . ' -' . ($day ? $day - 1 : 6) . ' days');
        $curMonday = date($format, $beginLastweek);
        $startDay = date($format, strtotime("$curMonday -7 days"));
        $data = [
            $startDay,
            date($format, strtotime("$startDay +1 days")),
            date($format, strtotime("$startDay +2 days")),
            date($format, strtotime("$startDay +3 days")),
            date($format, strtotime("$startDay +4 days")),
            date($format, strtotime("$startDay +5 days")),
            date($format, strtotime("$startDay +6 days")),
        ];
    } else {
        //获取当前周几
        //获取本周开始日期,如果$day是0是周日:-6天;其它:$day-1天
        $week = date('w', time()) - $day + 1;
        $data = [];
        for ($i = 1; $i <= 7; $i++) {
            $data[$i] = date($format, strtotime('+' . $i - $week . ' days'));
        }
    }

    return $data;
}
2.3、计算两日期相差天数

/**
 * 计算两日期相差天数
 * @param string $endTime 结束时间
 * @param string $startTime 开始时间
 * @param int $flag 传入日期格式(0-时间戳,1-日期格式)
 * @return false|float
 */
function calDifferentDay($endTime = '', $startTime = '', $flag = 1)
{
    //转换为天,取出时分秒
    $startTime = ($startTime == '') ? date('Y-m-d H:i:s', time()) : $startTime;
    $endTime = ($endTime == '') ? date('Y-m-d H:i:s', time()) : $endTime;

    if ($flag) {
        $startTime = strtotime($startTime);
        $endTime = strtotime($endTime);
    }

    $startTime = floor($startTime / 86400);
    $endTime = floor($endTime / 86400);
    return $endTime - $startTime;
}
2.4、检验日期格式是否正确
/**
 * 检验日期格式是否正确
 * @param string $date 日期格式是 2020-01-21
 * @return bool
 */
function validDate($date)
{
    //匹配日期格式
    if (preg_match("/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/", $date, $parts)) {
        //检测是否为日期,checkdate为月日年
        if (checkdate($parts[2], $parts[3], $parts[1])) return true;
        return false;
    }

    return false;
}

3、字符串/中文系列

3.1、将unicode转中文
/**
 * unicode转中文
 * @param string $name unicode
 * @return string
 */
function unicodeDecode($name)
{
    // 转换编码,将Unicode编码转换成可以浏览的utf-8编码
    $pattern = '/([\w]+)|(\\\u([\w]{4}))/i';
    preg_match_all($pattern, $name, $matches);
    if (!empty($matches)) {
        $name = '';
        for ($j = 0; $j < count($matches[0]); $j++) {
            $str = $matches[0][$j];
            if (strpos($str, '\\u') === 0) {
                $code = base_convert(substr($str, 2, 2), 16, 10);
                $code2 = base_convert(substr($str, 4), 16, 10);
                $c = chr($code) . chr($code2);
                $c = iconv('UCS-2', 'UTF-8', $c);
                $name .= $c;
            } else {
                $name .= $str;
            }
        }
    }
    return $name;
}
3.2、生成随机中文汉字
/**
 * 随机中文汉字
 * @param int $num 数量
 * @return string 返回随机中文汉字
 */
function getChineseChar($num)
{
    $ch = '';
    for ($i = 0; $i < $num; $i++) {
        // 使用chr()函数拼接双字节汉字,前一个chr()为高位字节,后一个为低位字节
        $chr = chr(mt_rand(0xB0, 0xD0)) . chr(mt_rand(0xA1, 0xF0));
        // 转码
        $ch .= iconv('GB2312', 'UTF-8', $chr);
    }
    return $ch;
}
3.3、生成随机字符串
/**
 * 生成随机字符串
 * @param int $length
 * @return string
 */
function getRandomStr($length = 6) {
    $chars = '123456789abcdefghijklmnpqrstuvwxyzABCDEFGHIJKLMNPQRSTUVWXYZ';
    $hash = '';
    $max = strlen($chars) - 1;
    for($i = 0; $i < $length; $i++) $hash .= $chars[mt_rand(0, $max)];

    return $hash;
}
3.4、可控的隐藏手机号
/**
 * @param string|int $str 手机号码
 * @param int $start 开始位置,从0开始
 * @param int $length 隐藏长度
 * @return bool|string|string[] 
 */
function hidePhone($str, int $start = 3, int $length = 4)
{
    //获取最后一位
    $end = $start + $length;
    //判断传参是否正确
    if ($start < 0 || $end > 11) return false;

    $replace = ''; //用于判断多少
    for ($i = 0; $i < $length; $i++) $replace .= '*';
    return substr_replace($str, $replace, $start, $length);
}
3.6、国内国际手机号正则匹配(待完善)
/**
 * 国内国际手机号正则匹配(待完善)
 * @param int $areaCode 国际区号
 * @param string $mobile 手机号
 * @return false|int
 */
function mathMobile(int $areaCode,string $mobile)
{
    if ($areaCode == 86) {
        //中国大陆 11位
        $reg = '/^1[3|4|5|7|8|9][0-9]{9}$/'; //手机正则匹配
    } elseif ($areaCode == 852) {
        //中国香港 8位
        $reg = '/^[9|6]\d{7}$/'; //手机正则匹配
    } elseif ($areaCode == 886) {
        //中国台湾
        $reg = '/^9{8}$/'; //手机正则匹配
    } elseif ($areaCode == 853) {
        //中国澳门
        $reg = '/^6[6|8]\d{6}$/'; //手机正则匹配
    }
    return preg_match($reg, $mobile);
}

3.6、阿拉伯数字转换成中文数字(例如:100 → 一百)
/**
 * @param int $num 阿拉伯数字
 * @return mixed|string
 */
function numToWord(int $num)
{
    $chiNum = array('零', '一', '二', '三', '四', '五', '六', '七', '八', '九');
    $chiUni = array('', '十', '百', '千', '万', '亿', '十', '百', '千');
    $num_str = (string)$num;
    $count = strlen($num_str);

    $last_flag = true; //上一个 是否为0
    $zero_flag = true; //是否第一个
    $temp_num = null; //临时数字
    $chiStr = '';//拼接结果

    if ($count == 2) {//两位数
        $temp_num = $num_str[0];
        $chiStr = $temp_num == 1 ? $chiUni[1] : $chiNum[$temp_num] . $chiUni[1];
        $temp_num = $num_str[1];
        $chiStr .= $temp_num == 0 ? '' : $chiNum[$temp_num];

    } else if ($count > 2) {
        $index = 0;
        for ($i = $count - 1; $i >= 0; $i--) {
            $temp_num = $num_str[$i];
            if ($temp_num == 0) {
                if (!$zero_flag && !$last_flag) {
                    $chiStr = $chiNum[$temp_num] . $chiStr;
                    $last_flag = true;
                }
            } else {
                $chiStr = $chiNum[$temp_num] . $chiUni[$index % 9] . $chiStr;
                $zero_flag = false;
                $last_flag = false;
            }
            $index++;
        }

    } else {
        $chiStr = $chiNum[$num_str[0]];
    }
    return $chiStr;
}
3.7、将图片转换成base64编码
/**
 * 将图片转换成base64编码
 * @param $image_path string 图片路径
 * @param bool $is_full 是否加上图片前缀
 * @return string
 */
function base64EncodeImage($image_path, $is_full = true)
{
    $base64_image = '';
    $image_info = getimagesize($image_path);
    $image_data = fread(fopen($image_path, 'r'), filesize($image_path));
    if ($is_full) {
        //data:image/jpg/png/gif;base64,
        $base64_image = 'data:' . $image_info['mime'] . ';base64,' . base64_encode($image_data);
    } else {
        $base64_image = base64_encode($image_data);
    }
    return $base64_image;
}
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,458评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,454评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,171评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,062评论 0 207
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,440评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,661评论 1 219
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,906评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,609评论 0 200
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,379评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,600评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,085评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,409评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,072评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,088评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,860评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,704评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,608评论 2 270

推荐阅读更多精彩内容

  • 首先给大家介绍javascript jquery中定义数组与操作的相关知识,具体内容如下所示: 1.认识数组 数组...
    JamHsiao_aaa4阅读 1,788评论 0 2
  • 一、数组定义 array() 1、索引数组 在一个变量中,存储一个或多个值。数组中的每一个元素都有一个访问ID,根...
    竹与豆阅读 509评论 0 0
  • 转载:在开发中,数组的使用场景非常多,平日中也涉及到很多数组的api/相关操作,一直也没有对这块内容进行一块整理总...
    七色烟火阅读 3,184评论 0 3
  • 排序的基本概念 在计算机程序开发过程中,经常需要一组数据元素(或记录)按某个关键字进行排序,排序完成的序列可用于快...
    Jack921阅读 1,361评论 1 4
  • 1.strlen()与mb_strlen()的作用分别是什么? strlen()和mb_strlen()都是作用于...
    落魄PHP女程序员阅读 327评论 0 2