<?php
if (!defined('puyuetian')) {
    exit('Not Found puyuetian!Please contact QQ632827168');
}
/*
 * puyuetianPHP轻框架 核心函数
 * 作者：蒲乐天（puyuetian）
 * QQ：632827168
 * 官网：http://www.puyuetian.com
 *
 * 作者允许您转载和使用，但必须注明来自puyuetianPHP轻框架。
 */

/********************************************
puyuetianPHP框架基础防火墙部分，因部分插件脱离puyuetian.php文件，所以在hs中将防火墙文件移至function.php文件中
 *******************************************/
require $_G['SYSTEM']['PATH'] . 'puyuetian/firewall/firewall.php';

//执行当前数据库语句，$returnFormat输出格式：0默认返回pdo对象，1仅返回找到的第一个值，2输出所有数据为数组
function sqlQuery($sql, $returnFormat = 0)
{
    global $_G;
    $r = $_G['PDO']->query($sql);
    if (!$returnFormat) {
        return $r;
    }
    if (!$r) {
        return false;
    }
    $array = array();
    $index = 0;
    while ($querya = $r->fetch(PDO::FETCH_ASSOC)) {
        if (InArray('1,onlyone', $returnFormat)) {
            foreach ($querya as $value) {
                return $value;
            }
        }
        $array[$index] = $querya;
        $index++;
    }
    if (InArray('2,array', $returnFormat)) {
        return $array;
    }
    return false;
}

function sqlError()
{
    global $_G;
    $array = $_G['PDO']->errorInfo();
    return $array[2];
}

//返回整数或小数数字，$str待处理字符，$return若非法返回的值，$int是否为整数（默认整数），$min数字最小值，$max数字最大值
function Cnum($str, $return = 0, $int = true, $min = false, $max = false)
{
    if (is_numeric($str)) {
        if ($int) {
            if (function_exists('bcadd')) {
                $str = bcadd($str, 0, 0);
            } else {
                $str = number_format($str, 0, '.', '');
            }
        }
    } else {
        $str = $return;
    }
    if (false !== $min) {
        if ($str < $min) {
            $str = $return;
        }
    }
    if (false !== $max) {
        if ($str > $max) {
            $str = $return;
        }
    }

    return $str;
}

//返回符合条件的字符串，$str待处理字符，$return若非法返回值，$cstr字符处理白名单，$minlen最小长度，$maxlen最大长度
function Cstr($str, $return = false, $cstr = true, $minlen = 3, $maxlen = 15)
{
    if (!is_string($str)) {
        return $return;
    }
    if (true === $cstr) {
        global $_G;
        $cstr = $_G['STRING']['SAFECHARS'];
    }
    $len = strlen($str);
    if ($cstr) {
        for ($i = 0; $i < $len; $i++) {
            $chk = strpos($cstr, substr($str, $i, 1));
            if (false === $chk) {
                return $return;
            }
        }
    }
    if ($minlen < $maxlen) {
        if ($len < $minlen) {
            return $return;
        }
        if ($len > $maxlen) {
            return $return;
        }
    } elseif ($minlen == $maxlen) {
        if ($len != $maxlen) {
            return $return;
        }
    }
    return $str;
}

// bbcode函数,若数据库设置了过滤标签则使用数据库的标签，否则使用系统默认标签，$marks保留的标签，$attrs保留的标签属性
// 更新：没有的标签自动去除
function BBcode($str, $marks = false, $attrs = false)
{
    global $_G;
    if (false === $marks) {
        $marks = ($_G['SET']['BBCODEMARKS'] ? $_G['SET']['BBCODEMARKS'] : $_G['STRING']['BBCODEMARKS']);
    }
    //第一次过滤
    $str = strip_tags($str, $marks);
    //第二次过滤
    if (!$marks) {
        return $str;
    }
    if (preg_match_all('/<(?!\/)([\s\S]+?)>/', $str, $match)) {
        // 获取允许的属性数据
        if (false === $attrs) {
            $attrs = ($_G['SET']['BBCODEATTRS'] ? $_G['SET']['BBCODEATTRS'] : $_G['STRING']['BBCODEATTRS']);
        }
        $attrs = explode(',', $attrs);
        foreach ($match[1] as $value2) {
            // exit($value2);
            //获取当前标签名
            $bqn = substr($value2, 0, strpos($value2, ' '));
            if (!$bqn) {
                // 该标签无属性
                continue;
            }
            $markhtml = "<{$bqn}";
            foreach ($attrs as $attr) {
                if (preg_match('/' . $attr . '="(.{0}|[\s\S]+?)"/i', $value2, $match2)) {
                    if (strtolower($bqn) == 'a' && strtolower($attr) == 'href') {
                        // 禁止href js
                        if (strpos(str_replace(array(" ", "　", "\r", "\n", "\t"), '', strtolower($match2[1])), 'javascript:') !== false) {
                            $match2[0] = 'href="#"';
                        }
                    }
                    // exit($match2[0]);
                    $markhtml .= " {$match2[0]}";
                }
            }
            $markhtml .= '>';
            // exit($markhtml);
            $str = str_replace("<{$value2}>", $markhtml, $str);
        }
    }
    return $str;
}

//html静态模板加载函数,$filename模板名称或路径，$return是则返回/否则输出，$htmlcode模板的内容，$isreplace是否解析模板,loadphpscript是否加载模板对应的php脚本,readphpscript是否读取模板嵌入的php代码(如果存在对应的脚本文件，默认不读取)
function template($templatevar_filename, $templatevar_return = false, $templatevar_htmlcode = false, $templatevar_isreplace = true, $templatevar_loadphpscript = true, $templatevar_readphpscript = null)
{
    global $_G;
    $templatevar_isnt = function ($path) {
        if (!$path) {
            return false;
        }
        if (strpos($path, '/') !== false || strpos($path, '\\') !== false) {
            $hstPath  = $path;
            $tDirPath = substr($path, 0, strrpos($path, '/')) . '/';
        } elseif (strpos($path, ':') !== false) {
            // 加载应用模板
            $appinfo     = explode(':', $path);
            $appname     = $appinfo[0];
            $apptemplate = $appinfo[1];
            if (!$appname) {
                $appname = sys('appdir');
            }
            if (!$apptemplate) {
                $apptemplate = sys('appfile');
            }
            if (!$appname || !$apptemplate) {
                error('出错');
            }
            $tDirPath = PK_APP_PATH . $appname . '/template/';
            $hstPath  = $tDirPath . $apptemplate . '.hst';
        } else {
            $tDirPath = PK_TEMPLATE_PATH . set('templatename') . '/';
            $hstPath  = $tDirPath . $path . '.hst';
        }
        if (file_exists($tDirPath . 'hadsky.v8') && file_exists($hstPath)) {
            return true;
        }
        return false;
    };
    if ($templatevar_isnt($templatevar_filename)) {
        $path = $templatevar_filename;
        if (!is_array($templatevar_return)) {
            $vars = [];
        } else {
            $vars = $templatevar_return;
        }
        $type = 'file';
        if ($templatevar_htmlcode) {
            $path = $templatevar_htmlcode;
            $type = 'code';
        }
        $parse = $templatevar_isreplace;
        if ($templatevar_return) {
            return nt($path, $vars, $type, $parse);
        } else {
            echo nt($path, $vars, $type, $parse);
            return;
        }
    }
    $templatevar_filename             = str_replace('\\', '/', $templatevar_filename);
    $_G['SYSTEM']['LOADTEMPLATENAME'] = $templatevar_filename;
    $templatevar_templatename         = $_G['SET']['TEMPLATENAME'];
    $templatevar_lj                   = str_replace('\\', '/', $_G['SYSTEM']['PATH']);
    $templatevar_cachecontent         = '';
    //获取模板的绝对路径
    if (strpos($templatevar_filename, '/') !== false && substr($templatevar_filename, strrpos($templatevar_filename, '.') + 1) != 'php') {
        //完整路径
        $templatevar_templatefullpath = $templatevar_filename;
    } elseif (strpos($templatevar_filename, ':')) {
        //应用模板加载
        $templatevar_plugname = explode(':', $templatevar_filename);
        if (count($templatevar_plugname) != 2) {
            RunError('插件模板必须遵循“插件目录:模板文件”规则，出错值：' . $templatevar_plugname);
        }
        $templatevar_templatefullpath = $templatevar_lj . "app/{$templatevar_plugname[0]}/template/{$templatevar_plugname[1]}.hst";
        if (!file_exists($templatevar_templatefullpath)) {
            $templatevar_templatefullpath = $templatevar_lj . "app/{$templatevar_plugname[0]}/template/{$templatevar_plugname[1]}.html";
        }
    } else {
        //一般模板加载
        $templatevar_templatefullpath = $templatevar_lj . "template/{$templatevar_templatename}/{$templatevar_filename}.hst";
        if (!file_exists($templatevar_templatefullpath)) {
            $templatevar_templatefullpath = $templatevar_lj . "template/{$templatevar_templatename}/{$templatevar_filename}.html";
        }
        if (!file_exists($templatevar_templatefullpath)) {
            if ($_G['SET']['DEFAULTTEMPLATES']) {
                $templatevar_trs       = explode(',', $_G['SET']['DEFAULTTEMPLATES']);
                $templatedefaultisload = false;
                foreach ($templatevar_trs as $templatevar_tr) {
                    $templatevar_v8_idpath          = $templatevar_lj . "template/{$templatevar_tr}/hadsky.v8";
                    $_templatevar_templatefullpath1 = $templatevar_lj . "template/{$templatevar_tr}/{$templatevar_filename}.hst";
                    $_templatevar_templatefullpath2 = $templatevar_lj . "template/{$templatevar_tr}/{$templatevar_filename}.html";
                    if (file_exists($_templatevar_templatefullpath1)) {
                        $templatevar_templatefullpath = $_templatevar_templatefullpath1;
                        $templatedefaultisload        = true;
                    } elseif (file_exists($_templatevar_templatefullpath2)) {
                        $templatevar_templatefullpath = $_templatevar_templatefullpath2;
                        $templatedefaultisload        = true;
                    }
                    if ($templatedefaultisload && file_exists($templatevar_v8_idpath)) {
                        $path = $templatevar_templatefullpath;
                        if (!is_array($templatevar_return)) {
                            $vars = [];
                        } else {
                            $vars = $templatevar_return;
                        }
                        $type = 'file';
                        if ($templatevar_htmlcode) {
                            $path = $templatevar_htmlcode;
                            $type = 'code';
                        }
                        $parse = $templatevar_isreplace;
                        if ($templatevar_return) {
                            return nt($path, $vars, $type, $parse);
                        } else {
                            echo nt($path, $vars, $type, $parse);
                            return;
                        }
                    }
                    if ($templatedefaultisload) {
                        break;
                    }
                }
            }
        }
    }

    //======================php模板文件缓存,是否开启了该功能,并存在相应的缓存文件,并且缓存文件未过期 1==============================
    $templatevar_cache_open = $_G['SET']['PHPCACHE_OPEN'];
    // 7.5.0之后彻底关闭该功能，如果开启请将下面的0该为1
    $templatevar_cache_open = 0;
    if (false !== $templatevar_htmlcode) {
        $templatevar_cache_open = 0;
    }
    if ($templatevar_cache_open) {
        $templatevar_cachefilename = $_G['SYSTEM']['PATH'] . 'cache/php/' . md5($templatevar_templatefullpath) . '.php';
        //是否存在缓存,若存在则加载缓存文件
        if (file_exists($templatevar_cachefilename)) {
            $templatevar_a = Cnum($_G['SET']['PHPCACHE_TIMEOUT'], 0, true, 0) * 60;
            $templatevar_b = 1;
            if ($templatevar_a) {
                $templatevar_c = filemtime($templatevar_cachefilename);
                if ($templatevar_c + $templatevar_a > time()) {
                    //缓存过期,需要重新创建缓存
                    $templatevar_b = 0;
                }
            }
            if ($templatevar_b) {
                if ($templatevar_return) {
                    //打开缓冲区
                    ob_start();
                    $templatevar_a =
                    include $templatevar_cachefilename;
                    $templatevar_a = ob_get_contents();
                    ob_end_clean();
                    return $templatevar_a;
                }
                require $templatevar_cachefilename;
                return;
            }
        }
    }
    //======================php模板文件缓存,是否开启了该功能,并存在相应的缓存文件,并且缓存文件未过期 2==============================

    if (false === $templatevar_htmlcode) {
        if (file_exists($templatevar_templatefullpath)) {
            $templatevar_htmlcode = file_get_contents($templatevar_templatefullpath);
        } else {
            RunError("不存在该模板文件：\"{$templatevar_templatefullpath}\"");
        }
    }

    $templatevar_cache_htmlcode = $templatevar_htmlcode;

    if ($templatevar_isreplace) {
        //加载脚本文件
        $templatevar_templatefullphpscriptpath = '';
        if ($templatevar_loadphpscript) {
            //获取脚本文件名称
            $templatevar_a = explode('/', $templatevar_templatefullpath);
            for ($templatevar_b = 0; $templatevar_b < count($templatevar_a); $templatevar_b++) {
                if ((count($templatevar_a) - 1) == $templatevar_b) {
                    $templatevar_templatefullphpscriptpath .= '/phpscript';
                    $templatevar_templatefullphpscriptpath .= '/' . current(explode('.', $templatevar_a[$templatevar_b])) . '.php';
                } else {
                    $templatevar_templatefullphpscriptpath .= '/' . $templatevar_a[$templatevar_b];
                }
            }
            $templatevar_templatefullphpscriptpath = substr($templatevar_templatefullphpscriptpath, 1);
            if (file_exists($templatevar_templatefullphpscriptpath)) {
                require $templatevar_templatefullphpscriptpath;
                //模板缓存写入
                if ($templatevar_cache_open) {
                    $templatevar_cachecontent .= '<?php include \'' . $templatevar_templatefullphpscriptpath . '\'; ?>' . "\n";
                }
                if (!$templatevar_readphpscript) {
                    $templatevar_readphpscript = false;
                }
            }
        }
        //模板内PHP脚本的执行
        if (($templatevar_readphpscript || null === $templatevar_readphpscript) && preg_match_all('#<\?php[\s\S]+?\?>#', $templatevar_htmlcode, $templatevar_match)) {
            foreach ($templatevar_match[0] as $templatevar_value2) {
                $templatevar_bl = substr($templatevar_value2, 5, strlen($templatevar_value2) - 7);
                eval("global \$_G;{$templatevar_bl}");
                $templatevar_htmlcode = str_replace($templatevar_value2, '', $templatevar_htmlcode);
                //生成缓存文件
                if ($templatevar_cache_open) {
                    $templatevar_cache_htmlcode = str_replace($templatevar_value2, '<?php ' . $templatevar_bl . ' ?>', $templatevar_cache_htmlcode);
                }
            }
        }
        //模板内变量的显示
        if (preg_match_all('#\{\$[A-Za-z0-9_\-\[\]\'\"]+?\}#', $templatevar_htmlcode, $templatevar_match)) {
            foreach ($templatevar_match[0] as $templatevar_value2) {
                $templatevar_bl       = substr($templatevar_value2, 2, strlen($templatevar_value2) - 3);
                $templatevar_cache_bl = $templatevar_bl;
                if (strpos($templatevar_bl, '[')) {
//防止数组被global
                    $templatevar_globalbl = substr($templatevar_bl, 0, strpos($templatevar_bl, '['));
                } else {
                    $templatevar_globalbl = $templatevar_bl;
                }
                eval("global \$" . $templatevar_globalbl . ";");
                eval("\$templatevar_bl=\$" . $templatevar_bl . ";");
                //防止PHP函数执行漏洞
                $templatevar_bl       = str_replace('{', '&#123;', $templatevar_bl);
                $templatevar_bl       = str_replace('}', '&#125;', $templatevar_bl);
                $templatevar_htmlcode = str_replace($templatevar_value2, $templatevar_bl, $templatevar_htmlcode);
                //生成缓存文件
                if ($templatevar_cache_open) {
                    $templatevar_cache_htmlcode = str_replace($templatevar_value2, '<?php global $' . $templatevar_globalbl . ';echo $' . $templatevar_cache_bl . '; ?>', $templatevar_cache_htmlcode);
                }
            }
        }
        //模板内函数的显示
        if (preg_match_all('#\{[\S ]+?\}#', $templatevar_htmlcode, $templatevar_match)) {
            foreach ($templatevar_match[0] as $templatevar_value2) {
                $templatevar_bl       = substr($templatevar_value2, 1, strlen($templatevar_value2) - 2);
                $templatevar_cache_bl = $templatevar_bl;
                $templatevar_a        = strpos($templatevar_bl, '(');
                if (function_exists(substr($templatevar_bl, 0, $templatevar_a))) {
                    $templatevar_b = '';
                    $templatevar_c = '';
                    if (preg_match_all('#\$([A-Za-z_]+)#', $templatevar_bl, $templatevar_b)) {
                        foreach ($templatevar_b[1] as $templatevar__v) {
                            eval('global $' . $templatevar__v . ';');
                            $templatevar_c .= 'global $' . $templatevar__v . ';';
                        }
                    }
                    if (substr($templatevar_bl, $templatevar_a + 1) == '$') {
                    }
                    eval("\$templatevar_bl=" . $templatevar_bl . ";");
                    $templatevar_htmlcode = str_replace($templatevar_value2, $templatevar_bl, $templatevar_htmlcode);
                    //生成缓存文件
                    if ($templatevar_cache_open) {
                        $templatevar_cache_htmlcode = str_replace($templatevar_value2, '<?php ' . $templatevar_c . 'echo ' . $templatevar_cache_bl . '; ?>', $templatevar_cache_htmlcode);
                    }
                }
            }
        }
        //还原被过滤的字符
        $templatevar_htmlcode = str_replace('&#123;', '{', $templatevar_htmlcode);
        $templatevar_htmlcode = str_replace('&#125;', '}', $templatevar_htmlcode);

        //存储缓存模板文件
        if ($templatevar_cache_open) {
            $templatevar_cachecontent .= $templatevar_cache_htmlcode;
            file_put_contents($templatevar_cachefilename, $templatevar_cachecontent);
        }
    }

    if ($templatevar_return) {
        return $templatevar_htmlcode;
    }
    echo $templatevar_htmlcode;
}

//mysql数据库转义,待过滤字符串，是否添加''，''两边添加的字符，是否强制添加''（false数字不添加）
function mysqlstr($str, $quto = true, $bwf = '', $must = true)
{
    global $_G;
    $str = $_G['PDO']->quote($str);
    $str = substr($str, 1, strlen($str) - 2);
    if ($quto && !is_numeric($str) || $must) {
        if ('%' == $bwf) {
            $str = str_replace('_', '\\_', $str);
        }
        $str = "'{$bwf}{$str}{$bwf}'";
    }
    return $str;
}

//获取当前文件的名称
function getFilename($hz = false)
{
    $url      = $_SERVER['SCRIPT_NAME'];
    $filename = end(explode('/', $url));
    if (!$hz) {
        $pos      = strripos($filename, '.');
        $filename = substr($filename, 0, $pos);
    }
    return $filename;
}

function fun_cunzai($funname)
{
    $pos = strpos($funname, "(");
    if ($pos) {
        $name = substr($funname, 0, $pos);
        if (function_exists($name)) {
            return true;
        } else {
            return false;
        }
    } else {
        return false;
    }
}

function getClientInfos($info = 'all')
{
    if ('all' == $info) {
        $infos = '浏览器标示：' . $_SERVER['HTTP_USER_AGENT'] . ' <br>
';
        $infos .= '客户端语言：' . $_SERVER['HTTP_ACCEPT_LANGUAGE'] . '
<br>
';
        $infos .= '客户端IP地址：' . $_SERVER['REMOTE_ADDR'];
    } elseif ('ip' == $info) {
        $IPaddress = '';
        if (isset($_SERVER)) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $IPaddress = $_SERVER['HTTP_X_FORWARDED_FOR'];
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $IPaddress = $_SERVER['HTTP_CLIENT_IP'];
            } else {
                $IPaddress = $_SERVER['REMOTE_ADDR'];
            }
        } else {
            if (getenv('HTTP_X_FORWARDED_FOR')) {
                $IPaddress = getenv('HTTP_X_FORWARDED_FOR');
            } elseif (getenv('HTTP_CLIENT_IP')) {
                $IPaddress = getenv('HTTP_CLIENT_IP');
            } else {
                $IPaddress = getenv('REMOTE_ADDR');
            }
        }
        if (strpos($IPaddress, ',') !== false) {
            $IPaddress = explode(',', $IPaddress);
            $IPaddress = $IPaddress[0];
        }
        $infos = $IPaddress;
    } else {
        $infos = $_SERVER[$info];
    }
    return htmlspecialchars(strip_tags($infos), ENT_QUOTES);
}

function chkuploadfilesuffix($suffix)
{
    if (!$suffix) {
        return false;
    }
    global $_G;
    return in_array($suffix, explode("|", $_G['SET']['UPLOADFILETYPES']));
}

//生成伪静态URL，$name为c参数，$parmas为生成的参数，$addparmas为动态参数添加，$delimiter为分割符，$suffix为生成的后缀
function ReWriteURL($name, $parmas = '', $addparmas = '', $delimiter = '-', $suffix = '.html')
{
    global $_G;
    if ($_G['SET']['REWRITEURL'] && (!$_G['USER']['ID'] || $_G['SET']['MUSTREWRITEURL'])) {
        if ($parmas) {
            $parmas = explode('&', $parmas);
            $url    = $name;
            foreach ($parmas as $value) {
                $value = explode('=', $value);
                $url .= $delimiter . $value[1];
            }
        } else {
            $url = $name;
        }
        $addparmas ? $url .= "{$suffix}?{$addparmas}" : $url .= $suffix;
    } else {
        $addparmas ? $url = "index.php?c={$name}&{$parmas}&{$addparmas}" : $url .= "index.php?c={$name}&{$parmas}";
    }
    return $url;
}

function __unset()
{
    foreach ($GLOBALS as $key => $value) {
        if (substr($key, 0, 2) == "__") {
            unset($GLOBALS[$key]);
        }
    }
}

function getShuXiang($datetime)
{
    $year = date('Y', $datetime);
    if ($year) {
        //1900年是鼠年
        $data  = array('鼠', '牛', '虎', '兔', '龙', '蛇', '马', '羊', '猴', '鸡', '狗', '猪');
        $index = ($year - 1900) % 12;
        return $data[$index];
    } else {
        return false;
    }
}

function getXingZuo($datetime)
{
    $date = (int) date('nd', $datetime);
    if ($date) {
        switch ($date) {
            case (120 <= $date && 218 >= $date):
                $xz = "水瓶";
                break;
            case (219 <= $date && 320 >= $date):
                $xz = "双鱼";
                break;
            case (321 <= $date && 419 >= $date):
                $xz = "白羊";
                break;
            case (420 <= $date && 520 >= $date):
                $xz = "金牛";
                break;
            case (521 <= $date && 621 >= $date):
                $xz = "双子";
                break;
            case (622 <= $date && 722 >= $date):
                $xz = "巨蟹";
                break;
            case (723 <= $date && 822 >= $date):
                $xz = "狮子";
                break;
            case (823 <= $date && 922 >= $date):
                $xz = "处女";
                break;
            case (923 <= $date && 1023 >= $date):
                $xz = "天秤";
                break;
            case (1024 <= $date && 1121 >= $date):
                $xz = "天蝎";
                break;
            case (1122 <= $date && 1221 >= $date):
                $xz = "射手";
                break;
            default:
                $xz = "摩羯";
                break;
        }
        return $xz;
    } else {
        return false;
    }
}

function getNianLing($datetime)
{
    return (date('Y', time()) - date('Y', $datetime));
}

function SerializeData($data, $key, $value = null)
{
    $__data = unserialize($data);
    if (null !== $value) {
        //数据更新
        if (!is_array($key)) {
            $key = explode(',', $key);
        }
        if (!is_array($value)) {
            $value = explode(',', $value);
        }

        if (count($key) == count($value)) {
            foreach ($key as $k => $k2) {
                $__data[$k2] = $value[$k];
            }
        } else {
            foreach ($key as $k => $k2) {
                $__data[$k2] = $value[0];
            }
        }

        $data = serialize($__data);
        return $data;
    } else {
        //数据读取
        return $__data[$key];
    }
}

//数据转Json处理，$data为json字符串，$key为要读取或写入的键名，$value为键值
function JsonData($data, $key = null, $value = null)
{
    $__data = json_decode($data, true);
    if (null !== $value) {
        //数据更新
        if (!is_array($key)) {
            $key = explode(',', $key);
        }
        if (!is_array($value)) {
            $value = explode(',', $value);
        }

        if (count($key) == count($value)) {
            foreach ($key as $k => $k2) {
                $__data[$k2] = $value[$k];
            }
        } else {
            foreach ($key as $k => $k2) {
                $__data[$k2] = $value[0];
            }
        }

        $data = json_encode($__data);
        return $data;
    } else {
        //数据读取
        if (null === $key) {
            return $__data;
        } else {
            return $__data[$key];
        }
    }
}

function HSCSArray(array $array, $flags = ENT_QUOTES, $encoding = 'UTF-8', $double_encode = true)
{
    foreach ($array as $key => $value) {
        if (is_string($value)) {
            $array[$key] = htmlspecialchars($value, $flags, $encoding, $double_encode);
        }
    }
    return $array;
}

function standardArray(&$array, $uppercase = true)
{
    if (is_array($array)) {
        foreach ($array as $key => $value) {
            if ($uppercase) {
                $keyTemp = strtoupper($key);
            } else {
                $keyTemp = strtolower($key);
            }
            if ($keyTemp != $key) {
                unset($array[$key]);
                $array[$keyTemp] = $value;
            }
            if (is_array($array[$keyTemp])) {
                standardArray($array[$keyTemp], $uppercase);
            }
        }
    }
}

//Unicode 汉子编码
function UnicodeEncode($str, $format = 'js')
{
    $str = json_encode($str);
    $str = str_replace('\"', '"', substr($str, 1, strlen($str) - 2));
    if ($format = 'css') {
        $str = str_replace('u', '', $str);
    } elseif ($format = 'html') {
        $str = str_replace('\u', '&#x', $str);
    }
    return $str;
}

//Unicode 汉子解码
function UnicodeDecode($str)
{
    return reset(json_decode('["' . str_replace('"', '\"', $str) . '"]'));
}

//$array为字符串或数组，$needle为要查找的值，若为字符串此值起作用$delimiter为分割符
function InArray($array, $needle, $delimiter = ',')
{
    if (!is_array($array)) {
        $array = explode($delimiter, $array);
    }
    if (!is_array($needle)) {
        $needle = explode($delimiter, $needle);
    }
    foreach ($needle as $value) {
        if (in_array($value, $array)) {
            return true;
        }
    }
    return false;
}

function EqualReturn($str, $old, $new)
{
    if ($str === $old) {
        return $new;
    } else {
        return $str;
    }
}

function RunError($err)
{
    global $_G;
    if (!$_G['SET']['RUNERRORDISPLAY']) {
        $err = '未开启运行错误详情显示，若您是管理员请在后台 - 首页 - 站点状态开启';
    }
    PkPopup('{title:"出错",content:"' . str_replace(array('"', '\\'), array('&quot;', '\\\\'), $err) . '",icon:2,close:function(){location.href="index.php"},hideclose:true,shade:true}');
}

function chkVerifycode($verifycode, $page)
{
    global $_G;
    if (($_G['SET']['APP_VERIFYCODE_LOAD'] && $verifycode && strtolower($verifycode) == strtolower($_SESSION['APP_VERIFYCODE_' . strtoupper($page)])) || ($_G['SET']['APP_VERIFYCODE_LOAD'] && !InArray($_G['SET']['APP_VERIFYCODE_PAGE'], $page) && InArray('chklogin,savereg,post', $_G['GET']['C'])) || !$_G['SET']['APP_VERIFYCODE_LOAD'] || InArray(getUserQX($_G['USER']['ID'], 'quanxian'), 'noverifycode')) {
        $_SESSION['APP_VERIFYCODE_' . strtoupper($page)] = '';
        return true;
    } else {
        $_SESSION['APP_VERIFYCODE_' . strtoupper($page)] = '';
        return false;
    }
}

function loadVerifycode($page, $t = '')
{
    global $_G;
    $_G['APP']['VERIFYCODE']['TYPE'] = $page;
    if ($_G['SET']['APP_VERIFYCODE_LOAD'] && InArray($_G['SET']['APP_VERIFYCODE_PAGE'], $page) && !InArray(getUserQX($_G['USER']['ID'], 'quanxian'), 'noverifycode')) {
        if ($t) {
            $t = '-' . $t;
        }
        if ($_G['SET']['APP_VERIFYCODE_OPENSLIDING']) {
            return template('verifycode:sliding' . $t, true);
        } else {
            return template('verifycode:verifycode' . $t, true);
        }
    }
}

//$chkuserloginarray为检测登录的数组，$chkloginqx是否检测用户具有登录权限
function UserLogin($chkuserloginarray, $chkloginqx = true, $autologin = true)
{
    global $_G;
    $userdata = $_G['TABLE']['USER']->getData($chkuserloginarray);
    if (!$userdata) {
        $_G['USERLOGINFAILEDINFO'] .= '用户名或密码错误';
        return false;
    }
    if (!InArray(getUserQX($userdata['id']), 'login') && $chkloginqx) {
        $_G['USERLOGINFAILEDINFO'] .= '无权登录，请联系管理员';
        return false;
    }
    //====================存入登录信息=======================
    $array['id']        = $userdata['id'];
    $array['data']      = JsonData($userdata['data'], 'logininfo', array(getClientInfos()));
    $array['loginip']   = getClientInfos('ip');
    $array['logintime'] = time();
    if (!$_G['SET']['USERMULTIPLEONLINE']) {
        //不允许多设备同时在线
        $array['session_token'] = CreateRandomString(16);
    }
    $_G['TABLE']['USER']->newData($array);
    //if ($_G['SET']['UIABC']) {
    //=====================cookies safe======================
    //setcookie('UIA', key_endecode($userdata['id'] . '|' . md5($userdata['password'] . $array['session_token']) . md5($array['session_token'])), time() + Cnum($_G['SET']['USERCOOKIESLIFE'], 1800, TRUE, 300));
    //} else {
    //=====================session safe======================
    $_SESSION['HS_UID']           = $array['id'];
    $_SESSION['HS_UGID']          = $userdata['groupid'];
    $_SESSION['HS_SESSION_TOKEN'] = md5($array['session_token']);
    //防止session欺骗重新生成srid
    session_regenerate_id(true);
    //}
    //==================更新数据==============================
    $userdata = $_G['TABLE']['USER']->getData($array['id']);
    //==================登录提示 邮箱==============================
    if (function_exists('sendmail') && ($_G['SET']['USERLOGINEMAILTIP'] || (1 == $userdata['id'] && $_G['SET']['SUPERMANLOGINEMAILTIP']))) {
        sendmail($userdata['email'], $_G['SET']['LOGOTEXT'] . ' - 账号登录提示', "亲爱的{$userdata['nickname']}（UID：{$userdata['id']}），您的账号在" . date('Y-m-d H:i:s', time()) . "登录，登录IP为" . getClientInfos('ip') . "，若非本人操作请尽快更改账号密码（{$_G['SYSTEM']['DOMAIN']}）。");
    }
    //==================登录提示 短信==============================
    if (function_exists('cloudSendSms') && $_G['SET']['ADMIN_LOGIN_NOTICE_PHONE'] && 1 == $userdata['id']) {
        $os = strtolower($_SERVER["HTTP_USER_AGENT"]);
        if (strpos($os, 'win')) {
            $os = 'window';
        } elseif (strpos($os, 'iphone')) {
            $os = 'iphone';
        } elseif (strpos($os, 'linux')) {
            $os = 'linux';
        } else {
            $os = '未知';
        }
        cloudSendSms($userdata['phone'], "logintip&username={$userdata['username']}&ipadress=" . getClientInfos('ip') . "&os={$os}&date=" . date('Y-m-d H:i:s'));
    }
    //是否设置了自动登录
    if ($autologin) {
        setcookie('UIA', base64_encode(key_endecode($userdata['id'] . '|' . md5($userdata['password'] . $userdata['session_token']) . md5($userdata['session_token']))), time() + Cnum($_G['SET']['USERCOOKIESLIFE'], 86400, true, 1800), '/', $_G['SET']['COOKIE_DOMAIN'] ? $_G['SET']['COOKIE_DOMAIN'] : null, false, true);
    }
    return $userdata;
}

function UserLogout($full = false)
{
    global $_G;
    setcookie('UIA', '', time() - 3600, '/', $_G['SET']['COOKIE_DOMAIN'] ? $_G['SET']['COOKIE_DOMAIN'] : null, false, true);
    if ($full) {
        $_SESSION = array();
    } else {
        $_SESSION['HS_UID'] = $_SESSION['HS_UGID'] = $_SESSION['HS_SESSION_TOKEN'] = '';
    }
}

function UIA()
{
    global $_G;
    $chkdata = false;
    if ($_COOKIE['UIA']) {
        $cookie = base64_decode($_COOKIE['UIA']);
        //自动登录检测
        $uia = explode('|', key_endecode($cookie, 'DE'));
        if (count($uia) == 2 && Cnum($uia[0]) && strlen($uia[1]) == 64) {
            //数据合法
            $uid     = $uia[0];
            $upw     = substr($uia[1], 0, 32);
            $ust     = substr($uia[1], 32);
            $chkdata = $_G['TABLE']['USER']->getData($uid);
            if ($chkdata) {
                if (md5($chkdata['password'] . $chkdata['session_token']) != $upw || md5($chkdata['session_token']) != $ust) {
                    //验证失败
                    $chkdata = false;
                }
            }
        }
    } elseif (Cnum($_SESSION['HS_UID'])) {
        //获取session用户id
        //读取此用户信息存在$_G['USER']数组中
        $chkdata = $_G['TABLE']['USER']->getData($_SESSION['HS_UID']);
        if ($chkdata) {
            if (md5($chkdata['session_token']) != $_SESSION['HS_SESSION_TOKEN']) {
                $chkdata = false;
            }
        }
    }
    //检验身份
    if ($chkdata) {
        //登录用户数据处理
        $_SESSION['HS_UID']           = $chkdata['id'];
        $_SESSION['HS_UGID']          = $chkdata['groupid'];
        $_SESSION['HS_SESSION_TOKEN'] = md5($chkdata['session_token']);
    } else {
        //清除登录信息
        UserLogout();
        //游客数据处理
        $chkdata       = json_decode($_G['SET']['GUESTDATA'], true);
        $chkdata['id'] = 0;
    }
    //用户权限排序显示
    $chkdata['quanxian'] = explode(',', $chkdata['quanxian']);
    if (is_array($chkdata['quanxian'])) {
        sort($chkdata['quanxian']);
        $__quanxian2         = $chkdata['quanxian'];
        $chkdata['quanxian'] = '';
        foreach ($__quanxian2 as $value) {
            $chkdata['quanxian'] .= ',' . $value;
        }
        $chkdata['quanxian'] = substr($chkdata['quanxian'], 1);
    }
    standardArray($chkdata);
    return $chkdata;
}

function CreateRandomString($len = 4, $str = false)
{
    if (!$str) {
        $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
    }
    $strlen = strlen($str);
    $nstr   = '';
    if (Cnum($len) > 0) {
        for ($i = 0; $i < $len; $i++) {
            $nstr .= substr($str, rand(0, $strlen - 1), 1);
        }
    }
    return $nstr;
}

//下载文件函数
function file_download($file_url, $new_name = '')
{
    if (!isset($file_url) || trim($file_url) == '') {
        exit('download file 500');
    }
    if (!file_exists($file_url)) {
//检查文件是否存在
        exit('download file 404');
    }
    $file_type = explode('.', $file_url);
    $file_type = $file_type[count($file_type) - 1];
    $file_name = date('YmdHis') . '.' . $file_type;
    //basename($file_url);
    $file_name = trim('' == $new_name) ? $file_name : urlencode($new_name) . '.' . $file_type;
    //打开文件
    $file_data = fopen($file_url, 'r');
    $file_size = filesize($file_url);
    //@ob_clean();
    //输入文件标签
    header("Content-type: application/octet-stream");
    header("Accept-Ranges: bytes");
    header("Content-Length: " . $file_size);
    header("Content-Disposition: attachment; filename=\"{$file_name}\"");
    //输出文件内容
    $buffer       = 1024;
    $buffer_count = 0;
    while (!feof($file_data) && $file_size - $buffer_count > 0) {
        $data = fread($file_data, $buffer);
        $buffer_count += $buffer;
        echo $data;
    }
    //echo fread($file_type, filesize($file_url));
    fclose($file_data);
    exit();
}

function httpBuildQuery($params)
{
    if (!is_array($params)) {
        return $params;
    }
    $query = http_build_query($params);
    foreach ($params as $k => $v) {
        if ('' === $v || null === $v) {
            $query .= '&' . urlencode($k) . '=';
        }
    }
    return $query;
}

function GetPostData($url, $post_data = '', $connecttimeout = 10, $timeout = 0)
{
    $ch = curl_init();
    // http_build_query 会丢弃空对象，所以弃用
    $post_data = httpBuildQuery($post_data);
    if (false === $ch) {
        $opts = [
            'http' => [
                'method'  => $post_data ? 'POST' : 'GET',
                'content' => $post_data,
                'timeout' => $connecttimeout,
            ],
        ];
        $context       = stream_context_create($opts);
        $file_contents = file_get_contents($url, false, $context);
    } else {
        curl_setopt($ch, CURLOPT_URL, $url);
        if ($post_data) {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
        }
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connecttimeout);
        if (Cnum($timeout)) {
            curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
        }
        curl_setopt($ch, CURLOPT_HEADER, false);
        //跳过SSL验证
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, '0');
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, '0');
        $file_contents = curl_exec($ch);
        curl_close($ch);
    }
    return $file_contents;
}

function isphonecome()
{
    $_SERVER['ALL_HTTP'] = isset($_SERVER['ALL_HTTP']) ? $_SERVER['ALL_HTTP'] : '';
    $mobile_browser      = '0';
    if (preg_match('/(up.browser|up.link|mmp|symbian|smartphone|midp|wap|phone|iphone|ipad|ipod|android|xoom)/i', strtolower($_SERVER['HTTP_USER_AGENT']))) {
        $mobile_browser++;
    }
    if ((isset($_SERVER['HTTP_ACCEPT'])) and (strpos(strtolower($_SERVER['HTTP_ACCEPT']), 'application/vnd.wap.xhtml+xml') !== false)) {
        $mobile_browser++;
    }
    if (isset($_SERVER['HTTP_X_WAP_PROFILE'])) {
        $mobile_browser++;
    }
    if (isset($_SERVER['HTTP_PROFILE'])) {
        $mobile_browser++;
    }
    $mobile_ua     = strtolower(substr($_SERVER['HTTP_USER_AGENT'], 0, 4));
    $mobile_agents = array('w3c ', 'acs-', 'alav', 'alca', 'amoi', 'audi', 'avan', 'benq', 'bird', 'blac', 'blaz', 'brew', 'cell', 'cldc', 'cmd-', 'dang', 'doco', 'eric', 'hipt', 'inno', 'ipaq', 'java', 'jigs', 'kddi', 'keji', 'leno', 'lg-c', 'lg-d', 'lg-g', 'lge-', 'maui', 'maxo', 'midp', 'mits', 'mmef', 'mobi', 'mot-', 'moto', 'mwbp', 'nec-', 'newt', 'noki', 'oper', 'palm', 'pana', 'pant', 'phil', 'play', 'port', 'prox', 'qwap', 'sage', 'sams', 'sany', 'sch-', 'sec-', 'send', 'seri', 'sgh-', 'shar', 'sie-', 'siem', 'smal', 'smar', 'sony', 'sph-', 'symb', 't-mo', 'teli', 'tim-', 'tosh', 'tsm-', 'upg1', 'upsi', 'vk-v', 'voda', 'wap-', 'wapa', 'wapi', 'wapp', 'wapr', 'webc', 'winw', 'winw', 'xda', 'xda-');
    if (in_array($mobile_ua, $mobile_agents)) {
        $mobile_browser++;
    }
    if (strpos(strtolower($_SERVER['ALL_HTTP']), 'operamini') !== false) {
        $mobile_browser++;
    }
    // Pre-final check to reset everything if the user is on Windows
    if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'windows') !== false) {
        $mobile_browser = 0;
    }
    // But WP7 is also Windows, with a slightly different characteristic
    if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']), 'windows phone') !== false) {
        $mobile_browser++;
    }
    if ($mobile_browser > 0) {
        return true;
    } else {
        return false;
    }
}

function key_endecode($String, $Type = 'EN', $Key = null)
{
    if (!$String) {
        return false;
    }
    global $_G;
    $return              = '';
    null === $Key ? $Key = md5($_G['SET']['KEY']) : $Key = md5($Key);
    for ($i = 0; $i < strlen($String); $i++) {
        $addascii = ord(substr($Key, ($i % 32), 1)) % 16;
        if (!$addascii) {
            $addascii = 1;
        }
        $trueascii = ord(substr($String, $i, 1));
        if (strtoupper($Type) == 'EN') {
            //加密
            $return .= chr($trueascii - $addascii);
        } else {
            //解密
            $return .= chr($trueascii + $addascii);
        }
    }
    return $return;
}

function LoadAppScript($s = null, $d = 'default', $p = 'phpscript')
{
    global $_G;
    if (null === $s) {
        $s = (string) $_G['GET']['S'];
    }
    if (!$s && 0 !== $s) {
        $s = $d;
    }
    $fp = "{$_G['SYSTEM']['PATH']}/app/{$_G['SYSTEM']['APPDIR']}/{$p}/{$s}.php";
    if (file_exists($fp)) {
        require $fp;
    } else {
        RunError("\"{$fp}\" doesn't exist");
    }
}

function ExitJson($datas = '', $state = false, $exit = true, $mustformat = true, $unescaped = true)
{
    $array          = array();
    $array['state'] = $state ? 'ok' : 'no';
    $array['code']  = $state ? 1 : 0;
    if ((is_string($datas) || is_numeric($datas) || (!$datas && !is_array($datas))) && $mustformat) {
        $array['msg']   = $datas;
        $array['datas'] = array('msg' => $datas);
    } else {
        $array['datas'] = $datas;
    }
    $array['data'] = $array['datas'];
    if ($unescaped && PHP_VERSION_ID >= 50400) {
        $array = json_encode($array, 320);
    } else {
        $array = json_encode($array);
    }
    if ($exit) {
        header('Content-type:application/json');
        exit($array);
    } else {
        return $array;
    }
}

function GetSafeCheck()
{
    foreach ($_GET as $key => $value) {
        $check = array('"', '>', '<', '\'', '(', ')', 'CONTENT-TRANSFER-ENCODING');
        if (!empty($value) && !json_decode($value)) {
            $value = strtoupper($value);
            foreach ($check as $_str) {
                if (strpos($value, $_str) !== false) {
                    return false;
                }
            }
        }
    }
    return true;
}

function StringSafeCheck($str)
{
    $check = array('"', '>', '<', '\'', '(', ')', 'CONTENT-TRANSFER-ENCODING');
    //$str = $_SERVER['REQUEST_URI'];
    if (!empty($str)) {
        $str = strtoupper(urldecode(urldecode($str)));
        foreach ($check as $_str) {
            if (strpos($str, $_str) !== false) {
                return false;
            }
        }
    }
    return true;
}

//退出并跳转
function ExitGourl($url)
{
    header('Location:' . $url);
    exit('<script>location.href="' . str_replace('"', '\\"', $url) . '"</script>');
}

//pkpopup提示框
function PkPopup($data)
{
    global $_G;
    if (is_array($data)) {
        $data = json_encode($data);
    }
    if (strpos(str_replace(' ', '', $data), 'submit:function(){') === false) {
        $data = '{
			submit:function(){
				if(document.referrer) {
					var h = location.protocol + "//" + location.host;
					if(document.referrer.substr(0,h.length) == h){
						history.back();
						location.href = document.referrer;
						return false;
					}
				}
				location.href = "index.php";
			},' . substr($data, 1);
    }
    $_G['SET']['WEBTITLE']  = '提示';
    $_G['HTMLCODE']['MAIN'] = '<script>$(function(){ppp(' . $data . ')})</script>';
    template($_G['SYSTEM']['PATH'] . 'template/default/main.hst');
    exit();
}

//内容图片的读取，html读取的内容，maxn最大读取的图片数，0为所有，noalt不读取的alt值(多个,分开)，true不获取base64编码的图片
function getHtmlImages($html, $maxN = 0, $noAlt = 'emotion', $nobase64 = false)
{
    $array = array();
    if (!preg_match_all('#<img.*?src="(.*?)".*?\>#', $html, $marks)) {
        return $array;
    }
    $s = 0;
    foreach ($marks[0] as $value) {
        if ($maxN && $maxN <= $s) {
            break;
        }
        $value = substr($value, 5, strlen($value) - 6) . ' ';
        if (preg_match_all('/([a-z_][a-z0-9_\-]+)\=(.*?) /i', $value, $attrs)) {
            $i = count($array);
            foreach ($attrs[1] as $k => $a) {
                $a = trim(strtolower($a));
                $v = trim($attrs[2][$k]);
                //去掉"、'
                if (strpos('"\'', substr($v, 0, 1)) !== false) {
                    $v = substr($v, 1);
                }
                if (strpos('"\'', substr($v, -1)) !== false) {
                    $v = substr($v, 0, strlen($v) - 1);
                }
                $array[$i][$a] = $v;
            }
            if ($noAlt && InArray(strtolower($noAlt), strtolower($array[$i]['alt']))) {
                unset($array[$i]);
                continue;
            }
            if ($nobase64 && strpos($array[$i]['src'], 'data:image/png;base64,') === 0) {
                unset($array[$i]);
                continue;
            }
            $s++;
        }
    }
    return $array;
}

/*
 * 内容视频的读取
 * @param  $html  读取的内容
 * @param  $maxn  最大读取的图片数，0为所有
 */
function getHtmlVideos($html, $maxN = 0)
{
    $array = array();
    if (!preg_match_all('#<video.*?src="(.*?)".*?\>#', $html, $marks)) {
        return $array;
    }
    $s = 0;
    foreach ($marks[0] as $value) {
        if ($maxN && $maxN <= $s) {
            break;
        }
        $value = substr($value, 5, strlen($value) - 6) . ' ';
        if (preg_match_all('/([a-z_][a-z0-9_\-]+)\=(.*?) /i', $value, $attrs)) {
            $i = count($array);
            foreach ($attrs[1] as $k => $a) {
                $a = trim(strtolower($a));
                $v = trim($attrs[2][$k]);
                //去掉"、'
                if (strpos('"\'', substr($v, 0, 1)) !== false) {
                    $v = substr($v, 1);
                }
                if (strpos('"\'', substr($v, -1)) !== false) {
                    $v = substr($v, 0, strlen($v) - 1);
                }
                $array[$i][$a] = $v;
            }
            $s++;
        }
    }
    return $array;
}

/**
 * 获取html里面指定对象
 * @param $html 待处理的html
 * @param $mark 待获取的mark字符串
 * @param $maxN 最多获取$mark的个数，0为全部获取
 * @return array [[attr=>value,]]
 */
function getHtmlMarks($html, $mark, $maxN = 0)
{
    $array = [];
    if (!preg_match_all('#\<' . $mark . ' .*?\>#', $html, $marks)) {
        return $array;
    }
    $s = 0;
    foreach ($marks[0] as $value) {
        if ($maxN && $maxN <= $s) {
            break;
        }
        // 若为<p>这种则排除
        // if (!self::in_arrays(substr($value, strlen($mark) + 1, 1), [' ', '>'])) {
        //     continue;
        // }
        $value = substr($value, strlen($mark) + 2, strlen($value) - strlen($mark) - 3) . ' ';
        if (preg_match_all('/([a-z_][a-z0-9_\-]+)\="(.*?)"/i', $value, $attrs)) {
            $i = count($array);
            foreach ($attrs[1] as $k => $a) {
                $a             = trim(strtolower($a));
                $v             = trim($attrs[2][$k]);
                $array[$i][$a] = $v;
            }
            $s++;
        }
    }
    return $array;
}

function finallyOutput($html)
{
    global $_G;
    if (is_array($_G['FOFS'])) {
        foreach ($_G['FOFS'] as $function_name) {
            if (function_exists($function_name)) {
                eval("\$html = {$function_name}(\$html);");
            }
        }
    }
    exit($html);
}

//管理编辑帖子函数,dos为展示的权限
function adminEditTipbox($type, $id, $dos = '')
{
    global $_G;
    if (!InArray('read,reply', strtolower($type)) || !$_G['USER']['ID']) {
        return false;
    }
    $type = strtolower($type);
    $data = $_G['TABLE'][strtoupper($type)]->getData(Cnum($id));
    if (!$data) {
        return false;
    }
    if ('read' == $type) {
        $sortid = $data['sortid'];
    } else {
        $readdata = $_G['TABLE']['READ']->getData($data['rid']);
        $sortid   = $readdata['sortid'];
    }
    $bkdata = $_G['TABLE']['READSORT']->getData($sortid);
    if (!$dos) {
        $dos = '';
        if ('read' == $type) {
            if (1 == $_G['USER']['ID']) {
                $dos .= ',activetop';
            }
            if (InArray(getUserQX(), 'superman') || 1 == $_G['USER']['ID']) {
                $dos .= ',top,high,locked,move';
            }
        } else {
            if (InArray(getUserQX(), 'admin') || 1 == $_G['USER']['ID'] || $readdata['uid'] == $_G['USER']['ID'] || InArray($bkdata['adminuids'], $_G['USER']['ID'])) {
                $dos .= ',top';
            }
        }
        if (InArray(getUserQX(), 'admin') || 1 == $_G['USER']['ID'] || InArray($bkdata['adminuids'], $_G['USER']['ID']) || (InArray(getUserQX(), 'edit' . $type) && $data['uid'] == $_G['USER']['ID'])) {
            $dos .= ',edit';
        }
        if (InArray(getUserQX(), 'admin') || 1 == $_G['USER']['ID'] || InArray($bkdata['adminuids'], $_G['USER']['ID']) || (InArray(getUserQX(), 'del' . $type) && $data['uid'] == $_G['USER']['ID'])) {
            $dos .= ',del';
        }
        $dos = substr($dos, 1);
    }
    if (InArray($dos, 'move') && !$_G['TEMP']['adminEditTipbox_bkdatas']) {
        $_G['TEMP']['adminEditTipbox_bkdatas'] = 1;
        $bkdatas                               = $_G['TABLE']['READSORT']->getDatas(0, 0, false, false, '`id`,`title`,`pid`,`rank`');
        $_G['SET']['EMBED_HEADMARKS'] .= '<script>var adminEditTipbox_bkdatas=' . json_encode($bkdatas) . '</script>';
    }
    if (!$dos) {
        return false;
    }
    return array('type' => $type, 'id' => $id, 'dos' => $dos);
}

function adminEditTipboxHTML($type, $id, $do = false)
{
    $a = adminEditTipbox($type, $id);
    if (!$a) {
        return '';
    }
    if (is_string($do)) {
        $do = ',function(){' . $do . '}';
    } elseif (is_array($do)) {
        $b = ',{';
        foreach ($do as $k => $v) {
            $b .= $k . ':function(){' . $v . '},';
        }
        $b .= '}';
        $do = $b;
    }
    if (!$do) {
        $do = '';
    }
    $b = 'adminEditTipbox(' . json_encode($a) . $do . ')';
    $b = htmlspecialchars($b, ENT_QUOTES);
    $b = str_replace(array('{', '}'), array('&#123;', '&#125;'), $b);
    return '<a class="pk-text-danger admin-edit-tipbox-btn" href="javascript:;" onclick="' . $b . '"><i class="fa fa-fw fa-gears"></i><span>管理</span></a>&nbsp;';
}

function userheadURL($uid = 0, $default = false, $base64 = false)
{
    global $_G;
    if (Cnum($uid, false, true, 1)) {
        $url = 'userhead/' . $uid . '.png';
        if (file_exists($_G['SYSTEM']['PATH'] . $url)) {
            if ($base64) {
                return 'data:image/png;base64,' . base64_encode(file_get_contents($_G['SYSTEM']['PATH'] . $url));
            }
            return $url;
        }
    } elseif (is_string($uid)) {
        $url = $uid;
        //若为远程地址则直接返回值
        if (substr($url, 0, 2) == '//' || substr($url, 0, 7) == 'http://' || substr($url, 0, 8) == 'https://') {
            return $url;
        }
        if (file_exists($_G['SYSTEM']['PATH'] . $url)) {
            if ($base64) {
                return 'data:image/png;base64,' . base64_encode(file_get_contents($_G['SYSTEM']['PATH'] . $url));
            }
            return $url;
        }
    }
    if ('rnd' == $default) {
        $url = 'template/default/img/randhead/' . rand(1, Cnum($_G['SET']['TEMPLATE_DEFAULT_RANDHEADCOUNT'], 24)) . '.png';
        if (file_exists($_G['SYSTEM']['PATH'] . $url)) {
            if ($base64) {
                return 'data:image/png;base64,' . base64_encode(file_get_contents($_G['SYSTEM']['PATH'] . $url));
            }
            return $url;
        }
    }
    if ($default) {
        $url = $default;
    }
    if (file_exists($_G['SYSTEM']['PATH'] . $url)) {
        if ($base64) {
            return 'data:image/png;base64,' . base64_encode(file_get_contents($_G['SYSTEM']['PATH'] . $url));
        }
        return $url;
    }
    $url = 'userhead/0.png';
    if (file_exists($_G['SYSTEM']['PATH'] . $url)) {
        if ($base64) {
            return 'data:image/png;base64,' . base64_encode(file_get_contents($_G['SYSTEM']['PATH'] . $url));
        }
        return $url;
    }
    return 'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAC0lEQVQYV2NgAAIAAAUAAarVyFEAAAAASUVORK5CYII=';
}

function returnString($str)
{
    return $str;
}

// 数据库表快捷调用函数，不会报错
function db($tablename, $is_exists = false)
{
    global $_G;
    $db = $_G['TABLE'][strtoupper($tablename)];
    if (!$db) {
        if ($is_exists) {
            return false;
        }
        return (new notfound());
    }
    return $db;
}

// ===================================== HS v8.0 ADD ====================================== //
// 以下方法8.0版本新增，老版本不支持
/**
 * 新版数据库调用
 * @param mixed $table 表名
 */
function table($table = '')
{
    return new db($table);
}

/**
 * 智能获取应用数据库数据
 * @param string $tablename 应用表名称
 * @param string $appname 应用目录
 */

function aTable(string $tablename, string $appname = '')
{
    if (!$appname) {
        $appname = sys('appdir');
    }
    return table("app_{$appname}_{$tablename}");
}

/**
 * 数组键名统一改为小写
 * @param mixed $arr 待更改的数组
 */
function arrKeyToLower($arr)
{
    if (!is_array($arr)) {
        return $arr;
    }
    $newArr = [];
    foreach ($arr as $k => $v) {
        $newArr[strtolower($k)] = arrKeyToLower($v);
    }
    return $newArr;
}
/**
 * 数组键名统一改为大写
 * @param mixed $arr 待更改的数组
 */
function arrKeyToUpper($arr)
{
    if (!is_array($arr)) {
        return $arr;
    }
    $newArr = [];
    foreach ($arr as $k => $v) {
        $newArr[strtoupper($k)] = arrKeyToUpper($v);
    }
    return $newArr;
}
/**
 * 数组值统一改为小写
 * @param mixed $arr 待更改的数组
 */
function arrValueToLower($arr)
{
    if (!is_array($arr)) {
        return strtolower($arr);
    }
    $newArr = [];
    foreach ($arr as $k => $v) {
        $newArr[$k] = arrValueToLower($v);
    }
    return $newArr;
}
/**
 * 数组值统一改为大写
 * @param mixed $arr 待更改的数组
 */
function arrValueToUpper($arr)
{
    if (!is_array($arr)) {
        return strtoupper($arr);
    }
    $newArr = [];
    foreach ($arr as $k => $v) {
        $newArr[$k] = arrValueToUpper($v);
    }
    return $newArr;
}
/**
 * 全局变量调用
 * @param mixed $key 共用变量name，设置时可以为数组key=>value，不区分大小写
 * @param mixed $value 为null是获取该key值，或不为null则为设置该key
 * @param string $key_prefix key值前缀
 */
function g($key = null, $value = null, string $key_prefix = '')
{
    global $_G;
    $g = arrKeyToUpper($_G);
    if ($key_prefix) {
        $key_prefix = trim($key_prefix, '.');
        if (!is_array($key)) {
            $key = $key ? $key_prefix . '.' . $key : $key_prefix;
        }
    }
    if (!$key) {
        return arrKeyToLower($g);
    }
    if (is_array($key)) {
        $key = arrKeyToUpper($key);
    } else {
        $key = strtoupper($key);
    }
    if ($key && null === $value) {
        // 设置数据
        if (is_array($key)) {
            foreach ($key as $k => $v) {
                g($k, $v, $key_prefix);
            }
            return true;
        }
        // 获取数据
        if (strpos($key, '.')) {
            $keys = explode('.', $key);
            foreach ($keys as $k => $v) {
                if (!isset($g[$v])) {
                    return null;
                }
                $g = $g[$v];
            }
            return arrKeyToLower($g);
        }
        return isset($g[$key]) ? arrKeyToLower($g[$key]) : null;
    }
    //设置数据
    // 不改变原有的$_G的key大小写（兼容）
    // $g = $_G;
    if (strpos($key, '.')) {
        $keys = explode('.', $key);
        $_g   = $g;
        $_k   = '';
        foreach ($keys as $k => $v) {
            $_k .= '[\'' . $v . '\']';
            if (!isset($_g[$v])) {
                $_g[$v] = [];
                eval('$g' . $_k . '=[];');
            }
            $_g = $_g[$v];
        }
        eval('$g' . $_k . '=$value;');
    } else {
        $g[$key] = $value;
    }
    $_G = $g;
    return true;
}

/**
 * 临时配置，该配置为临时配置
 * @param mixed $key 配置名称
 * @param mixed $value 为null是获取该配置值，或不为null则为设置该配置
 */
function temp($key = null, $value = null)
{
    return g($key, $value, 'temp');
}

/**
 * 读写配置，该配置为用户配置，可以更改
 * @param mixed $key 配置名称
 * @param mixed $value 为null是获取该配置值，或不为null则为设置该配置
 */
function set($key = null, $value = null)
{
    return g($key, $value, 'set');
}

/**
 * 追加g配置
 * @param string $key 配置名称
 * @param mixed $data 追加的数据，字符串或数组
 * @param boolean $prepend 数据之前还是之后，默认之后
 * @return boolean true/false
 */
function gConcat(string $key, $data = '', $prepend = false)
{
    $config = g($key);
    if (is_string($data)) {
        if (!$config && "0" !== $config) {
            $config = '';
        }
        if ($config && !is_string($config)) {
            return false;
        }
        if ($prepend) {
            $data .= $config;
        } else {
            $data = $config . $data;
        }
    } elseif (is_array($data)) {
        if (!$config) {
            $config = [];
        }
        if ($config && !is_array($config)) {
            return false;
        }
        if ($prepend) {
            $data = array_merge($data, $config);
        } else {
            $data = array_merge($config, $data);
        }
    } else {
        return false;
    }
    return g($key, $data);
}

/**
 * 追加set配置，setAdd别称
 * @param string $key 配置名称
 * @param mixed $data 追加的数据，字符串或数组
 * @return boolean true/false
 */
function setConcat(string $key, $data = '', $prepend = false)
{
    return setAdd($key, $data, $prepend);
}

/**
 * 追加set配置
 * @param string $key 配置名称
 * @param mixed $data 追加的数据，字符串或数组
 * @return boolean true/false
 */
function setAdd(string $key, $data = '', $prepend = false)
{
    return gConcat("set.{$key}", $data, $prepend);
}

/**
 * 智能获取或设置应用配置
 * @param string $appname 应用名称
 * @param string $setname 应用设置key
 * @param mixed  $value 设置的新值
 */

function aAS(string $setname, $value = null, string $appname = '')
{
    return aSet($appname ? $appname : sys('appdir'), $setname, $value);
}

/**
 * 获取或设置应用配置
 * @param string $appname 应用名称
 * @param string $setname 应用设置key
 * @param mixed  $value 设置的新值
 */
function aSet(string $appname, string $setname, $value = null)
{
    return set("app_{$appname}_{$setname}", $value);
}

/**
 * 获取或设置模板配置
 * @param string $templatename 应用名称
 * @param string $setname 应用设置key
 * @param mixed  $value 设置的新值
 */
function tSet(string $templatename, string $setname, $value = null)
{
    return set("template_{$templatename}_{$setname}", $value);
}

/**
 * 用户配置，当前登录的用户的信息，只可读取
 * @param mixed $key 配置名称
 */
function user($key = null)
{
    $user = g('user');
    if (file_exists(PK_USERHEAD_PATH . $user['id'] . '.png')) {
        $user['userhead'] = 'userhead/' . $user['id'] . '.png';
    } else {
        $user['userhead'] = 'userhead/0.png';
    }
    if (null === $key) {
        return $user;
    }
    return $user[$key];
}

/**
 * 用户组配置，当前登录的用户的用户组信息，只可读取
 * @param mixed $key 配置名称
 */
function usergroup($key = null)
{
    $group = g('usergroup');
    if (null === $key) {
        return $group;
    }
    return $group[$key];
}

/**
 * 系统配置，该配置为系统配置，不建议更改
 * @param mixed $key 配置名称
 * @param mixed $value 为null是获取该配置值，或不为null则为设置该配置
 */
function sys($key = null, $value = null)
{
    return g($key, $value, 'system');
}

/**
 * 成功 输出json数据并退出
 * @param mixed $data data数据或msg消息
 */
function success($data = null)
{
    return ExitJson($data, true);
}

/**
 * v8成功 输出json数据并退出
 * @param mixed $msg msg消息
 * @param mixed $data data数据
 */
function v8Success($msg = null, $data = null)
{

    header('Content-type:application/json');
    exit(json_encode([
        'code'  => 1,
        'state' => 'ok',
        'msg'   => $msg,
        'data'  => $data,
        'time'  => time(),
        'datas' => ['msg' => $msg],
    ], 320));
}

/**
 * 失败 输出json数据并退出
 * @param mixed $msg msg消息
 */
function error($msg = null)
{
    return ExitJson($msg);
}

/**
 * v8失败 输出json数据并退出
 * @param mixed $msg msg消息
 * @param mixed $data data数据
 */
function v8Error($msg = null, $data = null)
{
    header('Content-type:application/json');
    exit(json_encode([
        'code'  => 0,
        'state' => 'no',
        'msg'   => $msg,
        'data'  => $data,
        'time'  => time(),
        'datas' => ['msg' => $msg],
    ], 320));
}

function nt(string $path, array $vars = [], string $type = 'file', $parse = true)
{
    if ('code' == $type) {
        $html = $path;
    } else {
        sys('loadtemplatename', $path);
        $tDirPath = PK_TEMPLATE_PATH . set('templatename') . '/';
        $phpPath  = '';
        if (strpos($path, '/') !== false || strpos($path, '\\') !== false) {
            $hstPath = $path;
        } elseif (strpos($path, ':') !== false) {
            // 加载应用模板
            $appinfo     = explode(':', $path);
            $appname     = $appinfo[0];
            $apptemplate = $appinfo[1];
            if (!$appname) {
                $appname = sys('appdir');
            }
            if (!$apptemplate) {
                $apptemplate = sys('appfile');
            }
            if (!$appname || !$apptemplate) {
                error('出错');
            }
            $hstPath = PK_APP_PATH . $appname . '/template/' . $apptemplate . '.hst';
        } else {
            $hstPath = $tDirPath . $path . '.hst';
        }
        // 是否有对应的php文件
        $suffix = end(explode('.', basename($hstPath)));
        if ($suffix) {
            $suffix = '.' . $suffix;
        }
        $phpPath = substr($hstPath, 0, strrpos($hstPath, '/')) . '/phpscript/' . basename($hstPath, $suffix) . '.php';
        if (!file_exists($hstPath)) {
            error('没有找到模板文件:' . $path);
        }
        $html = '';
        if (file_exists($hstPath)) {
            $html = file_get_contents($hstPath);
        }
        if (file_exists($phpPath)) {
            $html = "{include('{$phpPath}')}\n{$html}";
        }
    }
    // 兼容旧版本
    // $html = "{php}global \$_G{/php}\n" . $html;
    if (!$parse) {
        return $html;
    }
    // 脚本缓存文件路径
    $md5        = md5(md5($path) . md5($html));
    $cache_path = PK_CACHE_PATH . 'php/' . $md5 . '.php';
    $init       = function ($vars, $cache_path) {
        // 是否存在该缓存文件
        if (!file_exists($cache_path)) {
            return false;
        }
        ob_start();
        $__Z7xIAtVHr_vars = $vars;
        $__Z7xIAtVHr_path = $cache_path;
        (function () use ($__Z7xIAtVHr_vars, $__Z7xIAtVHr_path) {
            // 带入变量
            if ($__Z7xIAtVHr_vars) {
                foreach ($__Z7xIAtVHr_vars as $__Z7xIAtVHr_k => $__Z7xIAtVHr_v) {
                    $$__Z7xIAtVHr_k = $__Z7xIAtVHr_v;
                }
            }
            include ($__Z7xIAtVHr_path);
        })();
        $__Z7xIAtVHr_r = ob_get_contents();
        ob_end_clean();
        return $__Z7xIAtVHr_r;
    };
    // 若存在脚本文件则加载
    $r = $init($vars, $cache_path);
    if (false !== $r) {
        return $r;
    }

    // 开始生成PHP模板文件
    // 包含模板
    if (preg_match_all('/\{include\(([\s\S]+?)\)\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php include({$v}); ?>", $html);
        }
    }
    //原生php
    if (preg_match_all('/\{php\}([\s\S]+?)\{\/php\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php {$v}; ?>", $html);
        }
    }
    //替换变量
    if (preg_match_all('/\{(\$[a-z0-9_\-"\>\'\.\[\]]+?)\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php echo isset({$v})?{$v}:''; ?>", $html);
        }
    }
    //替换函数
    if (preg_match_all('/\{\:([a-z0-9_\\\:]+\(\))\:\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php echo {$v}; ?>", $html);
        }
    }
    if (preg_match_all('/\{\:([a-z0-9_\\\:]+\([\s\S]+?\))\:\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php echo {$v}; ?>", $html);
        }
    }

    //实现foreach
    if (preg_match_all('/\{foreach ([\s\S]+?)\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php foreach{$v}{ ?>", $html);
        }
        $html = str_replace('{/foreach}', '<?php } ?>', $html);
    }
    //实现for
    if (preg_match_all('/\{for ([\s\S]+?)\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php for{$v}{ ?>", $html);
        }
        $html = str_replace('{/for}', '<?php } ?>', $html);
    }
    //实现if
    if (preg_match_all('/\{if ([\s\S]+?)\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php if{$v}{ ?>", $html);
        }
        if (preg_match_all('/\{elseif ([\s\S]+?)\}/i', $html, $match2)) {
            foreach ($match2[1] as $k2 => $v2) {
                $html = str_replace($match2[0][$k2], "<?php }elseif{$v2}{ ?>", $html);
            }
        }
        $html = str_replace('{else /}', '<?php }else{ ?>', $html);
        $html = str_replace('{/if}', '<?php } ?>', $html);
    }
    //实现switch
    if (preg_match_all('/\{switch ([\s\S]+?)\}/i', $html, $match)) {
        foreach ($match[1] as $k => $v) {
            $html = str_replace($match[0][$k], "<?php switch(strval{$v}){case null:break; ?>", $html);
        }
        if (preg_match_all('/\{case \'([\s\S]+?)\'\}/i', $html, $match2)) {
            foreach ($match2[1] as $k2 => $v2) {
                $html = str_replace($match2[0][$k2], "<?php case '{$v2}': ?>", $html);
            }
        }
        $html = str_replace('{break /}', '<?php break; ?>', $html);
        $html = str_replace('{default /}', '<?php default: ?>', $html);
        $html = str_replace('{/switch}', '<?php } ?>', $html);
    }
    //存储模板文件
    if (file_put_contents($cache_path, $html) === false) {
        error("缓存文件写入失败[path={$cache_path}]");
    }
    return $init($vars, $cache_path);
}

/**
 * 调用输入（get、post、request）
 * 举例input('a'); 获取_REQUEST内的a参数,默认被过滤处理
 * input('get.a'); 获取_GET内的a参数
 * input('get.a/s'); 获取a参数并转为字符串,目前仅支持字符串/s及数字/d
 * input('get.a/s,get.b/d') 获取get方法a参数及b参数，返回数组
 * input()，input('get.') input('post.') 获取所有被输入的参数
 * @param mixed $keys 参数集合或字符串，若为字符串多个用,分开
 * @param boolean $filter 是否对获取的数据安全过滤
 */
function input($keys = null, $filter = true)
{
    //input相关数据的统一整理处理
    $_input = function ($data, $keys, $filter = true) {
        $_data_clear_up = function ($keys, $data) {
            $keys = explode(',', $keys);
            $r    = [];
            foreach ($keys as $v) {
                if (strpos($v, '/')) {
                    list($key, $type) = explode('/', $v);
                    $get              = isset($data[$key]) ? $data[$key] : null;
                    if ('d' == $type) {
                        $r[$key] = cnum($get, 0);
                    } elseif ('s' == $type) {
                        $r[$key] = (string) $get;
                    } else {
                        $r[$key] = $get;
                    }
                } else {
                    $r[$v] = isset($data[$v]) ? $data[$v] : null;
                }
            }
            return $r;
        };
        $filter_data = function ($data, $filter) {
            if (true === $filter) {
                $filter = 'trim';
            }
            if ($filter) {
                $filters = explode(',', $filter);
                foreach ($filters as $func) {
                    if (!is_string($data)) {
                        foreach ($data as $k => $v) {
                            if (is_string($v) || is_numeric($v)) {
                                $data[$k] = call_user_func_array($func, [$v]);
                            }
                        }
                    } else {
                        $data = call_user_func_array($func, [$data]);
                    }
                }
            }
            return $data;
        };
        $r = null;
        if (!$keys) {
            $r = $data;
        } else {
            $r = $_data_clear_up($keys, $data);
        }
        if ($filter) {
            $r = $filter_data($r, $filter);
        }
        if (count($r) == 1 && $keys) {
            $r = reset($r);
        }
        return $r;
    };
    if (!$keys) {
        return $_input($_REQUEST, '', $filter);
    }
    if (is_string($keys)) {
        if ('get.' == $keys) {
            return $_input($_GET, '', $filter);
        } elseif ('post.' == $keys) {
            return $_input($_POST, '', $filter);
        }
        $keys = explode(',', $keys);
    }
    $data = [];
    foreach ($keys as $v) {
        $v  = trim($v);
        $do = 'request';
        if (strpos($v, 'get.') === 0) {
            $v  = substr($v, 4);
            $do = 'get';
        } elseif (strpos($v, 'post.') === 0) {
            $v  = substr($v, 5);
            $do = 'post';
        }
        $key = $v;
        if (strpos($v, '/')) {
            $key = current(explode('/', $v));
        }
        switch ($do) {
            case 'get':
                $data[$key] = $_input($_GET, $v, $filter);
                break;
            case 'post':
                $data[$key] = $_input($_POST, $v, $filter);
                break;
            default:
                $data[$key] = $_input($_REQUEST, $v, $filter);
                break;
        }
    }
    if (count($data) == 1) {
        return current($data);
    }
    return $data;
}

/**
 * 返回变量值，模板变量输出调用，默认html转义
 * @param string $var 变量名
 * @param boolean $htmlspecialchars 是否转义，默认转义
 */
function t($var, $htmlspecialchars = true)
{
    $r = '';
    if (is_string($var) || is_numeric($var)) {
        $r = (string) $var;
        if ($htmlspecialchars) {
            $r = htmlspecialchars($r, ENT_QUOTES);
        }
    } elseif (is_array($var) || is_object($var)) {
        $r = json_encode($var, 320);
        if ($htmlspecialchars) {
            $r = htmlspecialchars($r, ENT_QUOTES);
        }
    } else {
        $r = '';
    }
    return $r;
}

/**
 * 格式化文件大小显示
 * @param int $size 初始大小bytes
 * @param boolean $suffix 是否添加后缀
 */
function formatBytes($size, $suffix = true)
{
    $units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB'];
    for ($i = 0; $size >= 1024 && $i < 6; $i++) {
        $size /= 1024;
    }
    return round($size, 2) . ($suffix ? $units[$i] : '');
}

/**
 * 计算目录或文件大小
 * @param string $dir_path  目录/文件路径
 * @return int 单位bytes
 */
function dirSize($dir_path)
{
    if (is_file($dir_path)) {
        return filesize($dir_path);
    }
    if (!is_dir($dir_path)) {
        return 0;
    }
    $dirsize = 0;
    $dir     = opendir($dir_path);
    while ($fileName = readdir($dir)) {
        $file = $dir_path . '/' . $fileName;
        if ('.' != $fileName && '..' != $fileName) {
            if (is_dir($file)) {
                $dirsize += dirSize($file);
            } else {
                $dirsize += filesize($file);
            }
        }
    }
    closedir($dir);
    return $dirsize;
}

/**
 * 删除文件夹
 * @param string $dir 目录路径
 * @param boolean $delDir 是否删除路径文件夹
 * @return int 单位bytes
 */
function unDir($dir, $delDir = true)
{
    $i  = 0;
    $dh = opendir($dir);
    while ($file = readdir($dh)) {
        if ('.' != $file && '..' != $file) {
            $fullpath = $dir . '/' . $file;
            if (!is_dir($fullpath)) {
                if (unlink($fullpath)) {
                    $i++;
                }
            } else {
                $i += undir($fullpath);
            }
        }
    }
    closedir($dh);
    if ($delDir) {
        rmdir($dir);
    }

    return $i;
}
