php长期使用的算法
2020-08-13 本文已影响0人
骑蚂蚁上高速_jun
1.二维数组根据pid生成多维树 (注意:父级必须排在数组前面,降维的生成树方法)
主要用于 从数据库取出菜单后,需要组装的结构
/**
* @param array $items 需要生成树状结构的二维数组
* @param int $root 菜单 pid的根节点
*/
private static function buildTreeMenu(array $items,int $root=0){
$tree = $packData = [];
foreach ($items as $data) {
$packData[$data["menuId"]] = $data;
}
foreach ($packData as $key => $val) {
if ($val["pid"] == $root) {
//代表跟节点, 重点一
$tree[] = &$packData[$key];
} else {
//找到其父类,重点二
$packData[$val["pid"]]["childs"][] = &$packData[$key];
}
}
return $tree;
}
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;
}
}
}
}
- 二位数组排序
/**
* 二维数组根据键值排序
* @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); //重置键值
}
4.二维数组去重(支持多字段同时匹配去重)
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;
}
5.一层遍历实现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);
- 根据数组 分页
/**
* 将多维数组继续分页,自定义分页效果
* @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);
}
- 将时间戳转换成多久之前
/**
* 时间戳转换
* @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 . '前';
}
}
}
8.获取上周/本周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;
}
9.获取两个日期相差天数
/**
* 计算两日期相差天数
* @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;
}
10.生成可控的手机号码隐藏符号
/**
* @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);
}
- 阿拉伯数字转中文数字
/**
* @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;
}
12.将图片转成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;
}