封装php一些常用的功能

方文锋  2020-03-30 09:01:31  1193  首页学习PHP

  封装一些常用的函数。数据类型条件的判断,如判断身份是函数、字符串、数字、关联数组、某个值是否存在、是否是POST请求、是否是GET请求、是否是AJAX异步请求、字符串验证判断、是否是SSL协议、获取文件扩展名、获取客户端IP地址、返回毫秒、返回微秒、字符串分割为数组、生成随机字符串、字符串截取、输入过滤、获取数组的维度、数组排序、分页功能、多级列表相关、发生HTTP状态、文章发布时间、文件读取、变量值浏览器友好输出、强制下载文件等。

  更多的请看我的gitee链接: https://gitee.com/fang_wen_feng/my_php_plugCode/blob/phpcode/phpCode/public_functions.php 

<?php
/*** 一些类型条件判断 start ***/
/**
 * 获取数据类型
 * @param $var
 * @return string
 */
function get_type($var)
{
    if (is_array($var)) return "array";
    if (is_bool($var)) return "boolean";
    if (is_callable($var)) return "function reference";
    if (is_float($var)) return "float";
    if (is_int($var)) return "integer";
    if (is_null($var)) return "NULL";
    if (is_numeric($var)) return "numeric";
    if (is_object($var)) return "object";
    if (is_resource($var)) return "resource";
    if (is_string($var)) return "string";
    return "unknown type";
}

/**
 * 判断是否是函数
 * @param $argument
 * @return bool
 */
function is_function($argument)
{
    return isset($argument) && is_callable($argument);
}

/**
 * 判断是否是关联数组
 * @param $arr
 * @return bool
 */
function is_assoc($arr)
{
    return array_keys($arr) !== range(0, count($arr) - 1);
}

/**
 * 判断是否是数字
 * @param $value
 * @return bool
 */
function is_number($value)
{
    return gettype($value) === "integer" || gettype($value) === "double" ? true : false;
}

/**
 * 判断是否存在
 * @param $var
 * @param array $opt 这里的值代表了不存在的意思
 * @return bool
 */
function is_exist($var, $opt = array("", null, false))
{
    isset($var) || ($var = false);
    return !in_array($var, $opt, true);
}

/**
 * 是否是POST请求
 * @return bool
 */
function is_post()
{
    return strtolower($_SERVER["REQUEST_METHOD"]) == 'post';
}

/**
 * 是否是GET请求
 * @return bool
 */
function is_get()
{
    return strtolower($_SERVER["REQUEST_METHOD"]) == 'get';
}

/**
 * 是否是AJAX异步请求
 * @return bool
 */
function is_ajax()
{
    return isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest';
}

/**
 * 必须是字母
 * @param $str
 * @return false|int
 */
function is_alp($str)
{
    return preg_match('/^[a-zA-Z]+$/', $str);
}

/**
 * 验证必须是汉字
 * @param $str
 * @param string $encoding
 * @return false|int
 */
function is_chs($str, $encoding = 'utf-8')
{
    return strtolower($encoding) === 'utf-8' ? preg_match('/^[\x{4e00}-\x{9fa5}]+$/u', $str) : preg_match("/^[\x7f-\xff]+$/", $str);
}

/**
 * 必须是数字
 * @param $str
 * @return false|int
 */
function is_num($str)
{
    return preg_match('/^[0-9]+$/', $str);
}

/**
 * 必须是字母、数字、横线、下划线
 * @param $str
 * @return false|int
 */
function is_ald($str)
{
    return preg_match("/^[\-_—a-zA-Z0-9]+$/", $str);
}

/**
 * 必须是汉字、字母
 * @param $str
 * @param string $encoding
 * @param string $add_preg 额外添加的匹配字符
 * @return false|int
 */
function is_chsAlpha($str, $encoding = 'utf-8', $add_preg = '')
{
    return strtolower($encoding) === 'utf-8' ? preg_match('/^[a-zA-Z' . $add_preg . '\x{4e00}-\x{9fa5}]+$/u', $str) : preg_match("/^[a-zA-Z" . $add_preg . "\x7f-\xff]+$/", $str);
}

/**
 * 必须是汉字、字母和数字
 * @param $str
 * @param string $encoding
 * @param string $add_preg 额外添加的匹配字符
 * @return false|int
 */
function is_chsAlphaNum($str, $encoding = 'utf-8', $add_preg = '')
{
    return strtolower($encoding) === 'utf-8' ? preg_match('/^[a-zA-Z0-9' . $add_preg . '\x{4e00}-\x{9fa5}]+$/u', $str) : preg_match("/^[a-zA-Z0-9" . $add_preg . "\x7f-\xff]+$/", $str);
}

/**
 * 必须是汉字、字母、数字和下划线_及破折号-
 * @param $str
 * @param string $encoding
 * @param string $add_preg 额外添加的匹配字符
 * @return false|int
 */
function is_chsDash($str, $encoding = 'utf-8', $add_preg = '')
{
    return strtolower($encoding) === 'utf-8' ? preg_match('/^[\-_—a-zA-Z0-9' . $add_preg . '\x{4e00}-\x{9fa5}]+$/u', $str) : preg_match("/^[\-_—a-zA-Z0-9" . $add_preg . "\x7f-\xff]+$/", $str);
}

/**
 * 必须是电话号码(支持手机号码,3-4位区号,7-8位直播号码,1-4位分机号)
 * @param $str
 * @return false|int
 */
function is_phone($str)
{
    return preg_match('/((\d{11})|^((\d{7,8})|(\d{4}|\d{3})-(\d{7,8})|(\d{4}|\d{3})-(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1})|(\d{7,8})-(\d{4}|\d{3}|\d{2}|\d{1}))$)/', $str);
}

/**
 * 是否是日期
 * @param string $str
 * @param string $format
 * @return bool
 */
function is_date($str = '', $format = "Y-m-d")
{
    $search = ["Y", "m", "d", "H", "i", "s"];
    $replace = ["[0-9]{4}", "[0-9]{2}", "[0-9]{2}", "[0-9]{2}", "[0-9]{2}", "[0-9]{2}"];
    $format = str_replace($search, $replace, $format);
    return !!preg_match("/^$format$/i", $str);
}

/**
 * 是否是日期时间
 * @param string $str
 * @param string $format
 * @return bool
 */
function is_datetime($str = '', $format = "Y-m-d H:i:s")
{
    return is_date($str, $format);
}

/**
 * 判断是否SSL协议
 * @return boolean
 */
function is_ssl()
{
    if (isset($_SERVER['HTTPS']) && ('1' == $_SERVER['HTTPS'] || 'on' == strtolower($_SERVER['HTTPS']))) {
        return true;
    } elseif (isset($_SERVER['SERVER_PORT']) && ('443' == $_SERVER['SERVER_PORT'])) {
        return true;
    }
    return false;
}

/**
 * 必须是邮箱地址
 * @param $str
 * @return false|int
 */
function is_email($str)
{
    return preg_match('/^\w+([-+.]\w+)*@\w+([-.]\w+)*\.\w+([-.]\w+)*$/', $str);
}

/**
 * 是否是字符串
 * @param string|int|double $str
 * @return bool
 */
function y_string($str = '')
{
    return !in_array($str, array('', null, false), true) && (is_string($str) || is_numeric($str));
}
/*** 一些类型条件判断 end ***/
/*** [变量|字符串|数组]相关处理 start ***/
/**
 * 获取变量值
 * @return bool|*
 */
function get_vars(){
    $args = func_get_args();
    $var = false;
    foreach ($args as $arg) {
        if(is_exist($arg)){
            $var = $arg;
            break;
        }
    }
    return $var;
}

/**
 * 获取文件扩展名
 * @param string $file
 * @return mixed
 */
function get_extension($file)
{
    return end(explode('.', $file));
}

/**
 * 获取客户端IP地址
 * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
 * @return mixed
 */
function get_client_ip($type = 0)
{
    $type = $type ? 1 : 0;
    static $ip = NULL;
    if ($ip !== NULL) return $ip[$type];
    if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
        $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
        $pos = array_search('unknown', $arr);
        if (false !== $pos) unset($arr[$pos]);
        $ip = trim($arr[0]);
    } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
        $ip = $_SERVER['HTTP_CLIENT_IP'];
    } elseif (isset($_SERVER['REMOTE_ADDR'])) {
        $ip = $_SERVER['REMOTE_ADDR'];
    }
    // IP地址合法验证
    $long = sprintf("%u", ip2long($ip));
    $ip = $long ? array($ip, $long) : array('0.0.0.0', 0);
    return $ip[$type];
}

/**
 * 返回毫秒
 * @return float
 */
function m_second(){
    $t = strval(microtime());
    $l = explode(' ', $t);
    $s = $l[1];
    $ms = ~~(floatval($l[0]) * 1000);
    $v = strval($s) . str_pad(strval($ms), 3, '0', STR_PAD_LEFT);
    return (float)$v;
}

/**
 * 返回微秒
 * @return string
 */
function u_second(){
    $t = strval(microtime());
    $l = explode(' ', $t);
    $s = $l[1];
    $us = ~~(floatval($l[0]) * 1000000);
    $v = strval($s) . str_pad(strval($us), 6, '0', STR_PAD_LEFT);
    return $v;
}

function my_encode64($data){
    return rtrim(strtr(base64_encode($data), '+/', '-_'), '=');
}

function my_decode64($data){
    return base64_decode(str_pad(strtr($data, '-_', '+/'), strlen($data) % 4, '=', STR_PAD_RIGHT));
}

/**
 *把字符串分割为数组(一维数组)
 *@$str string  分割的字符串
 *@$charset string 字符串编码
 */
function str_cut($str, $charset = 'utf-8')
{
    $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
    preg_match_all($re[$charset], $str, $match);
    return $match[0];
}

/**
 * 返回随机字符串
 * @param int $l
 * @param string $mode
 * @param array $config
 * @param string $charset
 * @return string
 */
function randomString($l = 5, $mode = "n", $config = array(), $charset = "utf-8")
{
    $C = array(
        "n" => "0123456789",
        "s" => "abcdefghijklmnopqrstuvwxyz",
        "S" => "ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "ns" => "0123456789abcdefghijklmnopqrstuvwxyz",
        "nS" => "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "sS" => "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "nsS" => "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
        "hex" => "0123456789abcdef",
        "all" => "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-_^+*=|,.~!@#",
    );
    if (is_array($config) && count($config) > 0) {
        foreach ($config as $key => $value) {
            $C[$key] = str_cut($value, $charset);
        }
    }
    $mode = empty($C[$mode]) ? "n" : $mode;
    $str = "";
    if (is_array($C[$mode]) && count($C[$mode]) > 0) {
        for ($i = 0, $len = count($C[$mode]); $i < $l; $i++) {
            $str .= $C[$mode][mt_rand(0, $len - 1)];
        }
    } else {
        for ($i = 0, $len = strlen($C[$mode]); $i < $l; $i++) {
            $str .= $C[$mode][mt_rand(0, $len - 1)];
        }
    }
    return $str;
}

/**
 * 字符串截取和返回字符串的长度
 * @param string $str 要截取的字符串
 * @param int $start 字符串截取的初始位置,从0开始
 * @param int $length 字符串截取的长度
 * @param string $charset 字符串编码
 * @param bool $suffix 是否添加后缀
 * @param bool $strlen 是否返回字符串的长度(false不返回,true返回)
 * @return int|string
 */
function my_substr($str, $start = 0, $length, $charset = 'utf-8', $suffix = true, $strlen = false)
{
    $charset || ($charset = 'utf-8');
    //正则表达式匹配编码
    $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
    //返回字符串长度
    if ($strlen) {
        if (function_exists('mb_strlen')) {
            $count = mb_strlen($str, $charset);
        } elseif (function_exists('iconv_strlen')) {
            $count = iconv_strlen($str, $charset);
        } else {
            preg_match_all($re[$charset], $str, $match);
            $count = count($match[0]);
        }
        return $count;
    }
    //截取字符串
    if (function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    //字数不满添加后缀 ...
    if ($suffix) {
        $count = my_substr($str, $start, $length, $charset, false, true);
        if ($count > $length) {
            return $slice . '......';
        } else {
            return $slice;
        }
    } else {
        return $slice;
    }
}

/**
 * 返回字符串长度
 * @param string $str
 * @param string $charset
 * @return int
 */
function my_strlen($str, $charset = 'utf-8')
{
    $charset || ($charset = 'utf-8');
    //正则表达式匹配编码
    $re['utf-8'] = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
    $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
    $re['gbk'] = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
    $re['big5'] = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";

    //返回字符串长度
    if (function_exists('mb_strlen')) {
        $count = mb_strlen($str, $charset);
    } elseif (function_exists('iconv_strlen')) {
        $count = iconv_strlen($str, $charset);
    } else {
        preg_match_all($re[$charset], $str, $match);
        $count = count($match[0]);
    }
    return $count;
}

/**
 * 字符串分隔
 * @param string $str
 * @param int $split_length
 * @param string $charset
 * @return array|array[]|bool|false|string[]
 */
function my_str_split($str, $split_length = 1, $charset = 'utf-8')
{
    if (func_num_args() == 1 && strtolower($charset) === 'utf-8') {
        return preg_split('/(?<!^)(?!$)/u', $str);
    }
    if ($split_length < 1) {
        return false;
    }
    $len = my_strlen($str, $charset);
    $arr = array();
    for ($i = 0; $i < $len; $i += $split_length) {
        $s = my_substr($str, $i, $split_length, $charset, false);
        $arr[] = $s;
    }
    return $arr;
}

/**
 * 数据过滤函数
 * @param string|array $data 待过滤的字符串或字符串数组
 * @param bool $force 为true时忽略get_magic_quotes_gpc
 * @param bool $is_htmlspecialchars 为true时,防止被挂马,跨站攻击
 * @param bool $regexp 正则匹配转义字符
 * @return array|null|string|string[]
 */
function input($data, $force = false, $is_htmlspecialchars = false, $regexp = false)
{
    if (is_string($data)) {
        $data = trim($is_htmlspecialchars ? htmlspecialchars($data) : $data);
        if (($force == true) || (!get_magic_quotes_gpc())) {
            $data = addslashes($data); // 防止sql注入
        }
        if ($regexp) {
            if (is_array($regexp)) {
                $regexp = join('|', $regexp);
            }
            $data = preg_replace('/(' . $regexp . ')/', '\\\\$1', $data);
        }
        return $data;
    } elseif (is_array($data)) {
        foreach ($data as $key => $value) {
            $data[$key] = input($value, $force, $is_htmlspecialchars, $regexp);
        }
        return $data;
    } else {
        return $data;
    }
}

/**
 * 数据还原函数
 * @param string|array $data
 * @return array|string
 */
function out($data)
{
    if (is_string($data)) {
        return $data = stripslashes($data);
    } elseif (is_array($data)) {
        foreach ($data as $key => $value) {
            $data[$key] = out($value);
        }
        return $data;
    } else {
        return $data;
    }
}

/**
 * 文本输入
 * @param string $str
 * @return mixed|string
 */
function text_in($str)
{
    $str = strip_tags($str, '<br>');
    $str = str_replace(" ", "&nbsp;", $str);
    $str = str_replace("\n", "<br>", $str);
    if (!get_magic_quotes_gpc()) {
        $str = addslashes($str);
    }
    return $str;
}

/**
 * 文本输出
 * @param string $str
 * @return mixed|string
 */
function text_out($str)
{
    $str = str_replace("&nbsp;", " ", $str);
    $str = str_replace("<br>", "\n", $str);
    $str = stripslashes($str);
    return $str;
}

/**
 * html代码输入
 * @param string $str
 * @return null|string|string[]
 */
function html_in($str)
{
    $search = array(
        "'<script[^>]*?>.*?</script>'si", // 去掉 javascript
        "'<iframe[^>]*?>.*?</iframe>'si"  // 去掉iframe
    );
    $replace = array("", "");
    $str = @preg_replace($search, $replace, $str);
    $str = htmlspecialchars($str);
    if (!get_magic_quotes_gpc()) {
        $str = addslashes($str);
    }
    return $str;
}

/**
 * html代码输出
 * @param string $str
 * @return string
 */
function html_out($str)
{
    if (function_exists('htmlspecialchars_decode')) {
        $str = htmlspecialchars_decode($str);
    } else {
        $str = html_entity_decode($str);
    }
    $str = stripslashes($str);
    return $str;
}

/**
 * 输出html代码
 * @param string $str
 * @param string|array $del_tagName
 * @return null|string|string[]
 */
function out_html($str, $del_tagName = 'script|iframe')
{
    if(!empty($del_tagName) && is_string($del_tagName)){
        $del_tagName = explode('|',$del_tagName);
    }
    if(is_array($del_tagName)){
        foreach ($del_tagName as $index => $tagName) {
            if(!in_array(strtolower($tagName),array('br','hr','input','img','link','meta'))){
                $search[] = "/<{$tagName}[^>]*?>.*?<\/{$tagName}>/si";
            }else{
                $search[] = "/<{$tagName}[^>]*?>/si";
            }
            $replace[] = "";
        }
    }else{
        $search = array(
            "/<script[^>]*?>.*?<\/script>/si", //去掉 javascript
            "/<iframe[^>]*?>.*?<\/iframe>/si", //去掉 iframe
        );
        $replace = array("", "");
    }
    $str = preg_replace($search, $replace, $str);
    if (function_exists('htmlspecialchars_decode')) {
        $str = htmlspecialchars_decode($str);
    } else {
        $str = html_entity_decode($str);
    }
    $str = stripslashes($str);
    return $str;
}

/**
 * 使用回调函数进行字符串替换
 * @param string|string[] $pattern
 * @param string|callable|callable[] $callback
 * @param string|string[] $subject
 * @param int $limit
 * @return mixed|null|string|string[]
 */
function str_replace_callback($pattern = '', $callback = '', $subject = '', $limit = -1){
    if (y_string($pattern) && is_callable($callback) && y_string($subject)) {
        return preg_replace_callback($pattern, $callback, $subject, $limit);
    } elseif (is_array($pattern) && is_array($callback) && y_string($subject)) {
        foreach ($pattern as $key => $val) {
            is_callable($callback[$key]) && ($subject = preg_replace_callback($val, $callback[$key], $subject, $limit));
        }
        return $subject;
    } else {
        $args = func_get_args();
        return call_user_func_array('preg_replace_callback', $args);
    }
}

/**
 * 返回数组的维度
 * @$arr    array   数组
 * @return  number  数组的维度
 */
function arrayLevel($arr)
{
    $al = array(0);
    if (!function_exists('aL')) {
        function aL($arr, &$al, $level = 0)
        {
            if (is_array($arr)) {
                $level++;
                $al[] = $level;
                foreach ($arr as $k => $v) {
                    aL($v, $al, $level);
                }
            }
        }
    }
    aL($arr, $al);
    return max($al);
}

/**
 * 数组排序 使用例如: sortArrByManyField($arr,'id',SORT_DESC,'field2',SORT_ASC)
 * @return mixed|null
 * @throws Exception
 */
function sortArrByManyField()
{
    $args = func_get_args();
    if (empty($args)) {
        return null;
    }
    $arr = array_shift($args);
    if (!is_array($arr)) {
        throw new Exception("第一个参数不为数组");
    }
    foreach ($args as $key => $field) {
        if (is_string($field)) {
            $temp = array();
            foreach ($arr as $index => $val) {
                $temp[$index] = $val[$field];
            }
            $args[$key] = $temp;
        }
    }
    $args[] = &$arr;//引用值
    call_user_func_array('array_multisort', $args);
    return array_pop($args);
}

/**
 * 设置数组, 如: set_array($arr,'lv1.lv2',$value); set_array($arr,array('lv1','lv2'),$value);
 * @param $arr
 * @param string $name
 * @param string $value
 * @param int $index
 * @return mixed
 */
function set_array(&$arr, $name = '', $value = '', $index = 0)
{
    if ($name && is_array($name)) {
        $len = count($name);
        if ($len > 0 && $index < $len) {
            if (!isset($arr[$name[$index]]) || !is_array($arr[$name[$index]])) {
                $arr[$name[$index]] = array();
                if ($index == $len - 1) {
                    $arr[$name[$index]] = $value;
                    return $arr;
                }
            }
            set_array($arr[$name[$index]], $name, $value, $index + 1);
        }
    } elseif ($name && is_string($name) && strpos($name, '.') > 0) {
        $name = explode('.', $name);
        set_array($arr, $name, $value, $index);
    } else {
        $arr[$name] = $value;
    }
}

/**
 * 获取数组 如: get_array($arr,'lv1.lv2'); get_array($arr,array('lv1','lv2'));
 * @param $arr
 * @param $name
 * @param int $index
 * @return mixed
 */
function get_array(&$arr, $name, $index = 0)
{
    if ($name && is_array($name)) {
        $len = count($name);
        if ($len > 0 && $index < $len) {
            if ($index == $len - 1) {
                return $arr[$name[$index]];
            }
            return get_array($arr[$name[$index]], $name, (int)$index + 1);
        }
    } elseif ($name && is_string($name) && strpos($name, '.') > 0) {
        $name = explode('.', $name);
        return get_array($arr, $name, $index);
    } else {
        return $name ? $arr[$name] : $arr;
    }
}

/**
 * 设置和获取值【获取值如: C('aa.bb')、C(),设置值如:C('aa.bb',$value)、C($array_value)】
 * @param string|array $name
 * @param string|array $value
 * @return array|mixed
 */
function C($name = '', $value = '')
{
    static $data = array();

    if ($name && is_string($name) && $value) {
        //设置值
        set_array($data, $name, $value);
    } elseif ($name && is_array($name) && empty($value)) {
        //批量设置值
        foreach ($name as $k => $item) {
            $data[$k] = $item;
        }
    } elseif ($name && is_string($name) && empty($value)) {
        //获取值
        return get_array($data, $name);
    } else {
        //获取所有值
        return $data;
    }
}

/**
 * 二维数组查询(单字段查询),返回匹配项的数组(二维数组或者一维数组)
 * @param array $lv2_array 要查询的二维数组
 * @param string|callable $field 要查询的字段
 * @param string $options 查询表达式(=|>|<|>=|<=|<>|regexp|==|!=)
 * @param string|int|double $value 查询条件(值)
 * @param string $get_field 匹配的列名称(字段名称),不为空返回一维数组
 * @return bool|array
 */
function level2_array_query($lv2_array, $field = '', $options = '==', $value = '', $get_field = '')
{
    $options_filter = ['==', '=', '>', '<', '>=', '<=', 'regexp', '!=', '<>'];
    if (is_callable($field)) {
        foreach ($lv2_array as $index => $item) {
            if (in_array($field($lv2_array, $index, $item), [1, true, "1"], true)) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            }
        }
        return $get_field ? $lv1_array_field : $new_lv2_array;
    }
    if (arrayLevel($lv2_array) == 2 && $field !== '' && in_array(strtolower($options), $options_filter)) {
        foreach ($lv2_array as $index => $item) {
            if (strtolower($options) === 'regexp' && preg_match('/' . $value . '/i', $item[$field])) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            } elseif ($options === '>' && is_numeric($value) && $item[$field] > $value) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            } elseif ($options === '<' && is_numeric($value) && $item[$field] < $value) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            } elseif (in_array($options, ['!=', '<>']) && $item[$field] != $value) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            } elseif ($options === '>=' && is_numeric($value) && $item[$field] >= $value) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            } elseif ($options === '<=' && is_numeric($value) && $item[$field] <= $value) {
                $new_lv2_array[] = $item;
                $get_field && ($lv1_array_field[] = $item[$get_field]);
            } else {
                if (in_array($options, ['==', '=']) && $item[$field] == $value) {
                    //存储获取到的匹配项
                    $new_lv2_array[] = $item;
                    //存储获取到的匹配项的某个字段
                    $get_field && ($lv1_array_field[] = $item[$get_field]);
                }
            }
        }
        return $get_field ? $lv1_array_field : $new_lv2_array;
    }
    return false;
}

/**
 * 分页数据
 * @param $rowCount integer 总条数
 * @param $param array 引用传递参数 $request->param();
 * @param $g array 引用传递参数 $request->get();
 */
function paging($rowCount, &$param, &$g)
{
    ($param['page_rows']) or ($param['page_rows'] = 15);
    ($param['page']) or ($param['page'] = 1);

    //当前页数
    $g['page'] = intval($param['page']);
    //每页的行数
    $g['page_rows'] = intval($param['page_rows']);
    //总行数
    $g['rowCount'] = $rowCount;

    //总页数
    $g['pageCount'] = ($g['rowCount'] % $g['page_rows'] === 0) ? ($g['rowCount'] / $g['page_rows']) : ~~($g['rowCount'] / $g['page_rows']) + 1;
    //上一页
    $g['left_page'] = ($g['page'] - 1) > 0 ? $g['page'] - 1 : 1;
    //下一页
    $g['right_page'] = ($g['page'] + 1) < $g['pageCount'] ? $g['page'] + 1 : $g['pageCount'];
    //开始显示第几条
    $g['start'] = (($g['page'] - 1) * $g['page_rows'] + 1) > $g['rowCount'] ? $g['rowCount'] : ($g['page'] - 1) * $g['page_rows'] + 1;
    //结束显示第几条
    $g['end'] = ($g['start'] + $g['page_rows'] - 1) < $g['rowCount'] ? ($g['start'] + $g['page_rows'] - 1) : $g['rowCount'];

    //显示的分页数字按钮数量
    ($param['btn_num']) or ($param['btn_num'] = 5);
    $g['btn_num'] = intval($param['btn_num']);
    //显示的分页按钮值 [1][2][3][4]...
    $min = $g['page'] - (~~($g['btn_num'] / 2)) < 1 ? 1 : $g['page'] - (~~($g['btn_num'] / 2));
    ($g['btn_num'] % 2 === 0 && $g['page'] + 1 >= $g['pageCount']) and ($min++);
    if ($g['page'] + (~~($g['btn_num'] / 2)) > $g['pageCount']) {
        $min = $min - ($g['page'] + (~~($g['btn_num'] / 2) - $g['pageCount']));
        ($min < 1) and ($min = 1);
    }
    $max = $g['page'] + (~~($g['btn_num'] / 2)) > $g['pageCount'] ? $g['page'] + (~~($g['btn_num'] / 2)) : $g['pageCount'];
    for ($i = 0, $j = $min; $i < $g['btn_num']; $i++) {
        if ($j > $g['pageCount']) {
            break;
        }
        $g['btn_list'][] = $j;
        $j++;
    }
}
/*** [变量|字符串|数组]相关处理 end ***/

/*** 分级列表部分 start ***/
$GLOBALS['tree'] = array(
    'pid' => 'pid',
    'id' => 'id',
    'tableName' => 'tree',
);
/**
 * 无限级分类树
 * @$arr   array  传入二维数,里面的一维数组存在父id和id
 * @$pid   string 父id
 * @$di    string id
 * @return array 返回树型结构的数组(多维数组)
 */
function get_tree($arr)
{
    $items = array();
    $pid = $GLOBALS['tree']['pid'];
    $id = $GLOBALS['tree']['id'];
    foreach ($arr as $key => $value) {
        $items[$value[$id]] = $value;
    }
    $tree = array(); //格式化好的树
    foreach ($items as $key => $item) {
        if (isset($items[$item[$pid]])) {
            $items[$item[$pid]]['is_have_child'] = 1;  //标记改元素有子元素
            $items[$item[$pid]]['child'][] = &$items[$item[$id]];
        } else {
            $tree[] = &$items[$item[$id]];
        }
    }
    return $tree;
}

/**
 * 给树形结构的多维数组添加属性 level,add_str,用于分级列表显示
 * @$treeArr        array  多维数组(树形结构的多维数组,结合方法 get_tree() )
 * @$lv            number  用于记录子元素所在的层级
 * @$str1       string
 * @$str2       string
 */
function set_level(&$treeArr, $lv = 0, $str1 = '&nbsp;&nbsp;&nbsp;&nbsp;', $str2 = ' └ ')
{
    foreach ($treeArr as $key => $value) {
        if (isset($value['child'])) {
            set_level($treeArr[$key]['child'], $lv + 1, $str1, $str2);
        }
        $treeArr[$key]['level'] = $lv;
        $treeArr[$key]['add_str'] = add_str($lv, $str1, $str2);
    }
}

/**
 * @$new_arr    array       引用传入一个数组,用来组成一个新的二维数组(一个有层次的二维数组)
 * @$arrTree    array       树型结构的数组,多维数组,配合方法 get_tree() 使用
 */
function tree_level(&$new_arr, $arrTree)
{
    $pid = $GLOBALS['tree']['pid'];
    $id = $GLOBALS['tree']['id'];
    foreach ($arrTree as $key => $value) {
        if (isset($value['child'])) {
            $value_copy = $value;
            //$value_copy['level']= get_id_level($value[$id],$data);
            unset($value_copy['child']);
            $new_arr[] = $value_copy;
            unset($value_copy);
            tree_level($new_arr, $value['child']);
        } else {
            //$value['level']= get_id_level($value[$id],$data);
            $new_arr[] = $value;
        }
    }
}

/**
 * @$new_arr    array       引用传入一个数组,用来组成一个新的二维数组(一个有层次的二维数组,不去除子元素)
 * @$arrTree    array       树型结构的数组,多维数组,配合方法 get_tree() 使用
 */
function tree_level_all(&$new_arr, $arrTree)
{
    $pid = $GLOBALS['tree']['pid'];
    $id = $GLOBALS['tree']['id'];
    foreach ($arrTree as $key => $value) {
        if (isset($value['child'])) {
            $new_arr[] = $value;
            tree_level_all($new_arr, $value['child']);
        } else {
            $new_arr[] = $value;
        }
    }
}

function add_str($lv, $str1 = '&nbsp;&nbsp;&nbsp;&nbsp;', $str2 = ' └ ')
{
    for ($i = 0, $st = ''; $i < $lv; $i++) {
        $st .= $str1;
    }
    return $lv > 0 ? $st . $str2 : '';
}

/**
 * 获取多级列表
 * @$id_v       string id值,主要给该id值下的所有子元素设置 disabled 属性值为 1
 * @$lv         number 要显示的列表缩进级别
 * @data        array  二维数组,里面的一维数组存在父id和id
 * @return      array  返回有层次的二维数组
 */
function get_level_list($id_v = 1, $lv = 2, $data = '', $str1 = '&nbsp;&nbsp;&nbsp;&nbsp;', $str2 = ' └ ')
{
    $pid = $GLOBALS['tree']['pid'];
    $id = $GLOBALS['tree']['id'];
    if (is_array($data)) {
        foreach ($data as $key => $value) {
            if ($value[$id] == $id_v) {
                $table_data = $value;
                break;
            }
        }
        unset($key, $value);
    }

    //生成新的拥有层次的二维数组 ( $new_arr )
    $new_arr = array();
    $treeArr = get_tree($data);
    set_level($treeArr, 0, $str1, $str2);
    tree_level_all($new_arr, $treeArr);

    //筛选要渲染的元素(下面只显示二级缩进 列表)
    foreach ($new_arr as $key => $value) {
        if ($value['level'] > $lv) {
            unset($new_arr[$key]);
        }
    }

    //获取该元素的子元素 id(type_id)一维数组
    if (isset($table_data[$id])) {
        foreach ($new_arr as $k => $v) {
            if ($v[$id] == $table_data[$id]) {
                $treeArr1 = $v;
            }
        }
        tree_level($new_arr1, [$treeArr1]);
        $child_arr['c'] = $new_arr1;
        foreach ($child_arr['c'] as $key => $value) {
            $child_arr['n'][] = $value[$id];
        }
        isset($child_arr['n']) or ($child_arr['n'] = array());
        //给新数组添加属性方便前台模板渲染
        foreach ($new_arr as $key => $value) {
            $new_arr[$key]['add_str'] = add_str($value['level'], $str1, $str2);
            $new_arr[$key]['disabled'] = in_array($value[$id], $child_arr['n']) ? 1 : 0;
        }
        unset($child_arr);
    } else {
        foreach ($new_arr as $key => $value) {
            $new_arr[$key]['add_str'] = add_str($value['level'], $str1, $str2);
        }
    }
    unset($treeArr, $child_arr, $table_data, $new_arr1);
    return $new_arr;
}

/**
 * 获取树的路径
 * @param array $lv2_array  要查询的数组(二维数组)
 * @param array $new_array  存放查到的内容
 * @param int $id 要查找的子元素 id 值
 * @param string $id_field  查询的数组里面的id字段名称
 * @param string $pid_field  查询的数组里面的pid字段名称
 * @param bool $init
 * @param int $index
 * @return array
 */
function get_tree_path($lv2_array, &$new_array, $id = 0, $id_field = 'id', $pid_field = 'pid', $init = true, $index = 1)
{
    $index++;
    if (is_array($lv2_array) && count($lv2_array) > 0) {
        //是否格式化数组
        $init && ($lv2_array = reconfig_array($lv2_array, $id_field));
        $pid = $lv2_array[$id][$pid_field];
        $id = $lv2_array[$id][$id_field];
        //把当前的子元素添加入数组
        $init && $id && ($new_array[] = $lv2_array[$id]);
        if ($pid > 0) {
            $lv2_array[$pid] && ($new_array[] = $lv2_array[$pid]);
            //只允许 99 次递归,防止内存溢出
            ($index < 100) && get_tree_path($lv2_array, $new_array, $pid, $id_field, $pid_field, false, $index);
        }
    }
    return count($new_array) > 0 ? array_reverse($new_array,true) : false;
}

/**
 * 给多级列表添加字段 block 区块,用与记录下级跟上级之间的关系,更好的处理数据 【1.0】
 * @param array $new_lv2_array 引用变量,构建新的数组
 * @param array $lv2_array 二维关联数组(比如从数据库读取的数据)
 * @param bool $is_reconfig_array 是否整理数组
 * @param int $r 递归次数
 * @param int $r_max 限制最大递归次数,防止内存溢出奔溃(也可以当做多级列表级别)
 */
function set_tree_block(&$new_lv2_array, $lv2_array, $is_reconfig_array = true, $r = 1, $r_max = 10)
{
    error_reporting(5);
    $pid = $GLOBALS['tree']['pid'];
    $id = $GLOBALS['tree']['id'];
    if ($is_reconfig_array === true) {
        $items = array();
        foreach ($lv2_array as $index => $item) {
            $items[$item[$id]] = $item;
        }
        $new_lv2_array = $items;
    }
    foreach ($new_lv2_array as $index => $item) {
        if ($item[$pid] == 0) {
            $new_lv2_array[$index]['block'] = '0,';
        } elseif ($item[$pid] > 0 && $new_lv2_array[$item[$pid]] && $new_lv2_array[$item[$pid]]['block']) {
            $new_lv2_array[$index]['block'] || ($new_lv2_array[$index]['block'] = $new_lv2_array[$item[$pid]]['block'] . $new_lv2_array[$item[$pid]][$id] . ',');
        } else {
            continue;
        }
    }
    ($r < $r_max) && set_tree_block($new_lv2_array, $lv2_array, false, $r + 1, $r_max);
}
/*** 分级列表部分 end ***/

/**
 * 发送HTTP状态
 * @param integer $code 状态码
 * @return void
 */
function send_http_status($code)
{
    static $_status = array(
        // Informational 1xx
        100 => 'Continue',
        101 => 'Switching Protocols',
        // Success 2xx
        200 => 'OK',
        201 => 'Created',
        202 => 'Accepted',
        203 => 'Non-Authoritative Information',
        204 => 'No Content',
        205 => 'Reset Content',
        206 => 'Partial Content',
        // Redirection 3xx
        300 => 'Multiple Choices',
        301 => 'Moved Permanently',
        302 => 'Moved Temporarily ', // 1.1
        303 => 'See Other',
        304 => 'Not Modified',
        305 => 'Use Proxy',
        // 306 is deprecated but reserved
        307 => 'Temporary Redirect',
        // Client Error 4xx
        400 => 'Bad Request',
        401 => 'Unauthorized',
        402 => 'Payment Required',
        403 => 'Forbidden',
        404 => 'Not Found',
        405 => 'Method Not Allowed',
        406 => 'Not Acceptable',
        407 => 'Proxy Authentication Required',
        408 => 'Request Timeout',
        409 => 'Conflict',
        410 => 'Gone',
        411 => 'Length Required',
        412 => 'Precondition Failed',
        413 => 'Request Entity Too Large',
        414 => 'Request-URI Too Long',
        415 => 'Unsupported Media Type',
        416 => 'Requested Range Not Satisfiable',
        417 => 'Expectation Failed',
        // Server Error 5xx
        500 => 'Internal Server Error',
        501 => 'Not Implemented',
        502 => 'Bad Gateway',
        503 => 'Service Unavailable',
        504 => 'Gateway Timeout',
        505 => 'HTTP Version Not Supported',
        509 => 'Bandwidth Limit Exceeded'
    );
    if (isset($_status[$code])) {
        header('HTTP/1.1 ' . $code . ' ' . $_status[$code]);
        // 确保FastCGI模式下正常
        header('Status:' . $code . ' ' . $_status[$code]);
    }
}

/**
 * 解析简单的数据格式的字符串如 aa=value1,bb=value2
 * @param string $str
 * @param string $cut_str_level1
 * @param string $cut_str_level2
 * @return array|bool
 */
function my_get_data($str = '', $cut_str_level1 = ',', $cut_str_level2 = '=')
{
    if ($str) {
        $level1_arr = explode($cut_str_level1, $str);
        $data = array();
        if (is_array($level1_arr) && count($level1_arr) > 0) {
            foreach ($level1_arr as $key => $value) {
                $level2_arr = explode($cut_str_level2, $value);
                $k = trim($level2_arr[0]);
                unset($level2_arr[0]);
                $v = join($cut_str_level2, $level2_arr);
                $data[$k] = $v;
            }
        }
        return $data;
    }
    return false;
}

/**
 * 生成简单的数据格式的字符串 传入一维关联数组
 * @param string|array $data
 * @param string $cut_str_level1
 * @param string $cut_str_level2
 * @return bool|string
 */
function my_set_data($data = '', $cut_str_level1 = ',', $cut_str_level2 = '=')
{
    if (is_array($data) || is_object($data)) {
        $str = '';
        foreach ($data as $key => $value) {
            $str .= $key . $cut_str_level2 . $value . $cut_str_level1;
        }
        $str = trim($str, $cut_str_level1);
        return $str;
    }
    return false;
}

/**
 * 计算日期时间,返回时间戳
 * @param string|int $start_time 起始时间参数(YYYY-mm-dd HH:ii:ss | 10位数字)
 * @param int $year 年数
 * @param int $month 月数
 * @param int $day 日期数
 * @param int $hour 小时数
 * @param int $minute 分钟数
 * @param int $second 秒钟数
 * @return false|float|int|string
 */
function calculate_time($start_time = '', $year = 0, $month = 0, $day = 0, $hour = 0, $minute = 0, $second = 0)
{
    $se = 0;
    if (in_array($start_time, array('', 0, '0', null, false), true)) {
        $t = time();
    } elseif (preg_match('/^[0-9]{4}-[0-9]{2}-[0-9]{2} [0-9]{2}:[0-9]{2}:[0-9]{2}$/', $start_time)) {
        $t = strtotime($start_time);
    } elseif (preg_match('^[0-9]{10}$', strval($start_time))) {
        $t = strtotime(intval($start_time));
    }
    $Y = (int)date('Y', $t);
    $m = (int)date('m', $t);
    $d = (int)date('d', $t);
    $H = (int)date('H', $t);
    $i = (int)date('i', $t);
    $s = (int)date('s', $t);
    if (is_int($year)) {
        $Y = $Y + $year;
        ($Y < 0) && ($Y = 0);
    }
    if (is_int($month)) {
        $m = $m + $month;
        if ($m < 0) {
            $Y += ~~($m / 12) - 1;
            $m = 12 - abs($m % 12); //确认月份
        } elseif ($m === 0) {
            $Y = $Y - 1;
            $m = 12;//确认月份
        } elseif ($m > 0) {
            $Y += ($m % 12 === 0) ? ~~($m / 12) - 1 : ~~($m / 12);
            $m = ($m % 12 === 0) ? 12 - abs($m % 12) : abs($m % 12); //确认月份
        }
    }
    if (is_int($day)) {
        $se += $day * 86400;
    }
    if (is_int($hour)) {
        $se += $hour * 3600;
    }
    if (is_int($minute)) {
        $se += $minute * 60;
    }
    if (is_int($second)) {
        $se += $second;
    }
    $data_time_str = str_pad($Y, 4, '0', STR_PAD_LEFT) . "-" . str_pad($m, 2, '0', STR_PAD_LEFT) . "-$d $H:$i:$s";
    $data_time_str = strtotime($data_time_str);
    $data_time_str += $se;
    return $data_time_str;
}

/**
 * 发布时间
 * @param string|int $str
 * @param string $opt
 * @return array|mixed|string
 */
function release_time($str, $opt = "auto"){
    $t = time();
    $year = 0; $month = 0; $week = 0; $day = 0; $hour = 0; $minute = 0; $second = 0;
    if (is_datetime($str)) {
        $str = strtotime($str);
    }
    if (preg_match('/^[0-9]{10}$/', $str . "")) {
        $str = intval($str);
    }
    $difference = $t - $str;
    if ($difference > 0) {
        $year = ~~($difference / 31536000); //多少年前
        $month = ~~($difference / 2592000); //多少个月前
        $week = ~~($difference / 604800); //多少周前
        $day = ~~($difference / 86400); //多少天前
        $hour = ~~($difference / 3600); //多少小时前
        $minute = ~~($difference / 60); //多少分钟前
        $second = $difference; //多少秒前
    }
    $data = array(
        'year' => $year,
        'month' => $month,
        'week' => $week,
        'day' => $day,
        'hour' => $hour,
        'minute' => $minute,
        'second' => $second,
        'Y' => $year,
        'm' => $month,
        'd' => $day,
        'H' => $hour,
        'i' => $minute,
        's' => $second,
        'w' => $week,
        'message' => date("Y-m-d H:i:s", $str),
    );
    $dt = $data['message'];
    $auto_opt = preg_match("/^auto_\d+$/i",$opt);
    if (in_array($opt, array("year", "Y"))) {
        $data['message'] = "{$year}年前";
    } elseif (in_array($opt, array("month", "m"))) {
        $data['message'] = "{$month}个月前";
    } elseif (in_array($opt, array("week", "w"))) {
        $data['message'] = "{$week}周前";
    } elseif (in_array($opt, array("day", "d"))) {
        $data['message'] = "{$day}天前";
    } elseif (in_array($opt, array("hour", "H"))) {
        $data['message'] = "{$hour}个小时前";
    } elseif (in_array($opt, array("minute", "i"))) {
        $data['message'] = "{$minute}分钟前";
    } elseif (in_array($opt, array("second", "s"))) {
        $data['message'] = "{$second}秒前";
    } elseif (in_array($opt, array("auto", "auto_Y", "auto_m", "auto_d", "auto_H", "auto_i", "auto_s", "auto_w")) || $auto_opt) {
        if ($difference < 60) {
            $data['message'] = "{$second}秒前";
            ($opt === "auto_s") && ($data['message'] = $dt);
        }
        if ($difference >= 60 && $difference < 3600) {
            $data['message'] = "{$minute}分钟前";
            ($opt === "auto_i") && ($data['message'] = $dt);
        }
        if ($difference >= 3600 && $difference < 86400) {
            $data['message'] = "{$hour}个小时前";
            ($opt === "auto_H") && ($data['message'] = $dt);
        }
        if ($difference >= 86400 && $difference < 604800) {
            $data['message'] = "{$day}天前";
            ($opt === "auto_d") && ($data['message'] = $dt);
        }
        if ($difference >= 604800 && $difference < 2592000) {
            $data['message'] = "{$week}周前";
            ($opt === "auto_w") && ($data['message'] = $dt);
        }
        if ($difference >= 2592000 && $difference < 31536000) {
            $data['message'] = "{$month}个月前";
            ($opt === "auto_m") && ($data['message'] = $dt);
        }
        if ($difference > 31536000) {
            $data['message'] = "{$year}年前";
            ($opt === "auto_Y") && ($data['message'] = $dt);
        }
        if($auto_opt){
            $arr = explode('_',$opt);
            $arr[1] = intval($arr[1]); //多少秒
            ($difference >= $arr[1]) && ($data['message'] = $dt); //相差多少秒时,恢复默认值
        }
        return $data['message'];
    }
    return $data[$opt] ? $data[$opt] : $data;
}

/**
 * 文件读取,返回一维数组
 * @param string $file_path
 * @param int $start 开始行
 * @param int $end 结束行,$end <= 0 时,读到文件末尾
 * @param int $len 每行最大读取长度(字节)
 * @return array|bool
 */
function file_read($file_path = '', $start = 1, $end = -1, $len = 4096)
{
    if (y_string($file_path) && file_exists($file_path)) {
        $row = array();
        $f = fopen($file_path, 'r');
        $line = 1;
        if ($f) {
            while (!feof($f)) {
                $str = rtrim(fgets($f, $len));
                if ($line >= $start) {
                    $str && ($row[] = $str);
                }
                if ($end > 0 && $line >= $end) {
                    break;
                }
                $line++;
            }
        }
        fclose($f);
        return $row;
    }
    return false;
}

/**
 * 浏览器友好输出
 * @param  *  $var    
 * @param  boolean $echo   
 * @param  string  $label  
 * @param  boolean $strict 
 * @return string         
 */
function my_dump($var, $echo = true, $label = null, $strict = true)
{
    $label = ($label === null) ? '' : rtrim($label) . ' ';
    if (!$strict) {
        if (ini_get('html_errors')) {
            $output = print_r($var, true);
            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        } else {
            $output = $label . print_r($var, true);
        }
    } else {
        ob_start();
        var_dump($var);
        $output = ob_get_clean();
        if (!extension_loaded('xdebug')) {
            $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
            $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
        }
    }
    if ($echo) {
        echo($output);
        return null;
    } else
        return $output;
}

/**
 * 获取二维数组里的某个字段的列值(一维数组)
 * @param array $array_level2 二维数组及多维数组
 * @param string $field
 * @param $newarray
 */
function field_array($array_level2, $field = '', &$newarray)
{
    if (is_array($array_level2) && arrayLevel($array_level2) > 1) {
        foreach ($array_level2 as $key => $value) {
            if (isset($value[$field]) && $value[$field] !== '') {
                $newarray[] = $value[$field];
            }
        }
    }
}

/**
 * @param array $array_level2 二维数组及多维数组
 * @param string $index_field 设置某个字段的值为 数组下标
 * @return array
 */
function reconfig_array($array_level2 = '', $index_field = 'id')
{
    $arr = array();
    if (is_array($array_level2) && arrayLevel($array_level2) > 1) {
        foreach ($array_level2 as $k => $v) {
            $arr[$v[$index_field]] = $v;
        }
    }
    return $arr;
}

/**
 * 清除html标签
 * @param string $str
 * @return null|string|string[]
 */
function del_html_tag($str = '')
{
    $preg['tag'] = '/<.+?>/i';
    if (!is_array($str) || !is_object($str)) {
        $str = preg_replace($preg['tag'], '', $str);
    }
    return $str;
}

/**
 * 清除字符串里面的某些字符
 * @param string $str
 * @param array $filter
 * @return null|string|string[]
 */
function string_filter($str = '', $filter = array("&nbsp;", "&emsp;", "\r", "\n", "\t"))
{
    is_array($filter) && ($preg = join('|', $filter));
    return preg_replace("/($preg)/i", '', $str);
}

/**
 * 构成文章的上一篇和下一篇的数据
 * @param array $lv2_array 二维数组【从数据库中获取的】
 * @param array $g
 * @param string $id
 */
function detail_prev_next($lv2_array, &$g, $id = 'id')
{
    $count = count($lv2_array);
    $Last = array(); //上一篇
    $Next = array(); //下一篇
    foreach ($lv2_array as $key => $item) {
        if ($item[$id] == $g[$id]) {
            if ($key - 1 >= 0) {
                $Last = $lv2_array[$key - 1];
            }
            if ($key + 1 <= $count) {
                $Next = $lv2_array[$key + 1];
            }
            break;
        }
    }
    $g['last'] = $Last;
    $g['next'] = $Next;
}

/**
 * @return mixed|string
 */
function get_path_info()
{
    if ($_SERVER['REDIRECT_PATH_INFO']) {
        return trim($_SERVER['REDIRECT_PATH_INFO'], '/');
    } elseif ($_SERVER['PATH_INFO']) {
        return trim($_SERVER['PATH_INFO'], '/');
    } elseif ($_SERVER['REQUEST_URI']) {
        $REQUEST_URI = preg_replace('/\?+.*/i', '', $_SERVER['REQUEST_URI']);
        $SCRIPT_NAME = str_replace('/', '\\/', $_SERVER['SCRIPT_NAME']);
        $REQUEST_URI = preg_replace('/' . $SCRIPT_NAME . '/i', '', $REQUEST_URI, 1);
        return trim($REQUEST_URI, '/');
    } else {
        return trim(str_replace($_SERVER['SCRIPT_NAME'] . '/', '', $_SERVER['PHP_SELF']), '/');
    }
}

/**
 * 强制下载文件
 * @param string $file 文件路径
 * @param string $rename 重命名文件名称
 */
function to_download($file,$rename='')
{
    //First, see if the file exists
    if (!is_file($file)) {
        die("<b>404 File not found!</b>");
    }
    //Gather relevent info about file
    $len = filesize($file);
    $filename = basename($file);
    //$file_extension = strtolower(substr(strrchr($filename, "."), 1));
    $file_extension = strtolower(end(explode('.', $filename)));

    //This will set the Content-Type to the appropriate setting for the file
    switch ($file_extension) {
        case "pdf":
            $ctype = "application/pdf";
            break;
        case "txt":
            $ctype = "application/txt";
            break;
        case "exe":
            $ctype = "application/octet-stream";
            break;
        case "zip":
            $ctype = "application/zip";
            break;
        case "doc":
            $ctype = "application/msword";
            break;
        case "xls":
            $ctype = "application/vnd.ms-excel";
            break;
        case "ppt":
            $ctype = "application/vnd.ms-powerpoint";
            break;
        case "gif":
            $ctype = "image/gif";
            break;
        case "png":
            $ctype = "image/png";
            break;
        case "jpeg":
        case "jpg":
            $ctype = "image/jpg";
            break;
        case "mp3":
            $ctype = "audio/mpeg";
            break;
        case "wav":
            $ctype = "audio/x-wav";
            break;
        case "mpeg":
        case "mpg":
        case "mpe":
            $ctype = "video/mpeg";
            break;
        case "mov":
            $ctype = "video/quicktime";
            break;
        case "avi":
            $ctype = "video/x-msvideo";
            break;

        //The following are for extensions that shouldn't be downloaded (sensitive stuff, like php files)
        case "php":
        case "htm":
        case "html":
            //case "txt":
            die("<b>Cannot be used for " . $file_extension . " files!</b>");
            break;
        default:
            $ctype = "application/force-download";
    }

    //Begin writing headers
    header("Pragma: public");
    header("Expires: 0");
    header("Cache-Control: must-revalidate, post-check=0, pre-check=0");
    header("Cache-Control: public");
    header("Content-Description: File Transfer");

    //Use the switch-generated Content-Type
    header("Content-Type: $ctype");

    $rename && ($filename = $rename . '.' . $file_extension);
    //Force the download
    $header = "Content-Disposition: attachment; filename=" . $filename . ";";
    header($header);
    header("Content-Transfer-Encoding: binary");
    header("Content-Length: " . $len);
    ob_clean();
    flush();
    @readfile($file);
    exit;
}