'Error', E_WARNING => 'Warning', E_PARSE => 'Parsing Error', E_NOTICE => 'Notice', E_CORE_ERROR => 'Core Error', E_CORE_WARNING => 'Core Warning', E_COMPILE_ERROR => 'Compile Error', E_COMPILE_WARNING => 'Compile Warning', E_USER_ERROR => 'User Error', E_USER_WARNING => 'User Warning', E_USER_NOTICE => 'User Notice', E_STRICT => 'Runtime Notice' ); $user_errors = array(E_USER_ERROR, E_USER_WARNING, E_USER_NOTICE); $filename = str_replace("\\", '/', $filename); $dt = date('Y-m-d H:i:s'); $err = "#####" . $dt . "\n"; $err .= "```" . "\n"; $err .= "datetime :" . $dt . "\n"; $err .= "errornum :" . $errno . "\n"; $err .= "errormsg :" . $errortype[$errno] . "\n"; $err .= "errortype :" . $errmsg . "\n"; $err .= "scriptname :" . $filename . "\n"; if (in_array($errno, $user_errors)) { $err .= "scriptname :" . wddx_serialize_value($vars, "Variables") . "\n"; } $err .= "scriptlinenum:" . $linenum . "\n"; $err .= "```\n"; $logDir = PROJECT_PATH . DS . 'Storage' . DS . 'Logs' . DS . 'SysError' . DS; $logFile = $logDir . date('m-d') . '.md'; if (!is_dir($logDir)) { @mkdir($logDir); } @error_log($err, 3, $logFile); @chmod($logFile, 0777); } function shutdown_function() { $e = error_get_last(); if (isset($e['type'])) { if (in_array($e['type'], array(E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR))) { php_error_log($e['type'], $e['message'], $e['file'], $e['line'], NULL); } } } if (defined('LOG_ERROR') && LOG_ERROR) { register_shutdown_function('shutdown_function'); } function isMobile($mobile) { return preg_match('#^13[\d]{9}$|^14[5,7]{1}\d{8}$|^15[^4]{1}\d{8}$|^16[\d]{9}$|^17[0,6,7,8,3,5]{1}\d{8}$|^18[\d]{9}$|^19[\d]{9}$#', $mobile) ? true : false; } /**电子邮箱格式校验*/ function isEmail($email) { $pattern = "/^([0-9A-Za-z\\-_\\.]+)@([0-9a-z]+\\.[a-z]{2,3}(\\.[a-z]{2})?)$/i"; return preg_match_all($pattern, $email) ? true : false; } /** * 利用curl模拟浏览器发送请求 * * @param string $url 请求的URL * @param array|string $post post数据 * @param int $timeout 执行超时时间 * @param boolean $sendcookie 是否发送当前cookie * @param array $options 可选的CURL参数 * @return array */ function request($url, $post = null, $timeout = 40, $sendcookie = true, $options = array(), $ssl = false, $sslDate = array(), $useragent = false, $proxy = false, $http_build_query = true) { if (empty($useragent)) { if (isset($_SERVER['HTTP_USER_AGENT'])) { $useragent = $_SERVER['HTTP_USER_AGENT']; } else { $useragent = 'internalloginuseragent'; } } if ($proxy) { $ip_long = array( array('607649792', '608174079'), //36.56.0.0-36.63.255.255 array('1038614528', '1039007743'), //61.232.0.0-61.237.255.255 array('1783627776', '1784676351'), //106.80.0.0-106.95.255.255 array('2035023872', '2035154943'), //121.76.0.0-121.77.255.255 array('2078801920', '2079064063'), //123.232.0.0-123.235.255.255 array('-1950089216', '-1948778497'), //139.196.0.0-139.215.255.255 array('-1425539072', '-1425014785'), //171.8.0.0-171.15.255.255 array('-1236271104', '-1235419137'), //182.80.0.0-182.92.255.255 array('-770113536', '-768606209'), //210.25.0.0-210.47.255.255 array('-569376768', '-564133889'), //222.16.0.0-222.95.255.255 ); $rand_key = mt_rand(0, 9); $ip = long2ip(mt_rand($ip_long[$rand_key][0], $ip_long[$rand_key][1]));//随机生成国内某个ip $result = getNewProxyId(); if ($result['error'] != '') { echo $result['error']; } else { $rand_ip = $result['ip']; } $baseHeader = array( "CLIENT-IP:{$ip}", "X-FORWARDED-FOR:{$ip}", ); if (isset($options[CURLOPT_HTTPHEADER])) { $options[CURLOPT_HTTPHEADER] = array_merge($options[CURLOPT_HTTPHEADER], $baseHeader); } } $ch = curl_init($url); curl_setopt($ch, CURLOPT_HEADER, 0); curl_setopt($ch, CURLOPT_USERAGENT, $useragent); curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 35); curl_setopt($ch, CURLOPT_TIMEOUT, $timeout ? $timeout : 40); if (defined('CURLOPT_IPRESOLVE') && defined('CURL_IPRESOLVE_V4')) { curl_setopt($ch, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4); } if ($sendcookie) { $cookie = ''; foreach ($_COOKIE as $key => $val) { $cookie .= rawurlencode($key) . '=' . rawurlencode($val) . ';'; } curl_setopt($ch, CURLOPT_COOKIE, $cookie); } if ($post) { curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, (is_array($post) && $http_build_query) ? http_build_query($post) : $post); } if (!ini_get('safe_mode') && ini_get('open_basedir') == '') { curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); } curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); //检查证书中是否设置域名且是否与提供的主机名匹配 curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); //是否只信任CA颁发的证书 curl_setopt($ch, CURLOPT_SSLVERSION, 1); //CURL_SSLVERSION_TLSv1 if ($ssl) { /*curl_setopt($ch, CURLOPT_SSLCERT, '/apps/jindouyun/Public/upload/apiclient_cert.pem'); curl_setopt($ch, CURLOPT_SSLKEY, '/apps/jindouyun/Public/upload/apiclient_key.pem');*/ curl_setopt($ch, CURLOPT_SSLCERT, $sslDate['cert']); curl_setopt($ch, CURLOPT_SSLKEY, $sslDate['key']); } foreach ($options as $key => $value) { curl_setopt($ch, $key, $value); } if ($proxy && isset($rand_ip)) { curl_setopt($ch, CURLOPT_PROXY, 'http://' . $rand_ip); } $ret = curl_exec($ch); $httpcode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $content_length = curl_getinfo($ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD); if (!$content_length) $content_length = curl_getinfo($ch, CURLINFO_SIZE_DOWNLOAD); $info = curl_getinfo($ch); $content_type = curl_getinfo($ch, CURLINFO_CONTENT_TYPE); $errorMsg = curl_error($ch); curl_close($ch); return array( 'httpcode' => $httpcode, 'info' => $info, 'errorMsg' => $errorMsg, 'content_length' => $content_length, 'content_type' => $content_type, 'content' => $ret ); } /** * 获取最新的代理ip * 代理测试工具 http://proxies.site-digger.com/proxy-test/ **/ function getNewProxyId() { //$url = 'http://webapi.http.zhimacangku.com/getip?num=1&type=2&pro=&city=0&yys=0&port=1&time=1&ts=1&ys=1&cs=1&lb=1&sb=0&pb=4&mr=1®ions='; $url = 'http://http.tiqu.qingjuhe.cn/getip?num=1&type=2&pack=35299&port=1&lb=1&pb=4®ions='; $data = request($url); if ($data['httpcode'] == 200) { $content = json_decode($data['content'], true); if ($content['success'] == 'true') { foreach ($content['data'] as $key => $value) { $rand_ip = $value['ip'] . ':' . $value['port']; } } else { $errorMessage = '获取代理ip失败' . $content['code'] . $content['msg'] . PHP_EOL; } } if (isset($rand_ip)) { return [ 'ip' => $rand_ip, 'error' => '', ]; } else { return [ 'ip' => '', 'error' => $errorMessage, ]; } } /** * 获取当前毫秒时间戳 */ function msectime() { list($msec, $sec) = explode(' ', microtime()); return (int)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000); } /** * 断点调试输出方法 * * @param mixed $msg 输出的内容 * * @return string */ function V($msg) { echo "
";
    var_export($msg);
    exit();
}

/**
 * 校验日期格式是否正确
 *
 * @param string $date 日期
 * @param array $formats 需要检验的格式数组
 *
 * @return bool|int
 */
function checkDateIsValid($date, $formats = ["Y-m-d", "Y/m/d", "Y-m-d H:i:s", "Y/m/d H:i:s"])
{
    $unixTime = strtotime($date);
    if (!$unixTime) {
        return false;
    }

    foreach ($formats as $format) {
        if (date($format, $unixTime) == $date) {
            return $unixTime;
        }
    }

    return false;
}

/**
 * 二维数组根据某个字段排序
 *
 * @param array $needArray 需要排序的二维数组
 * @param string $field 根据的字段排序
 * @param array $sort 排序规则ASC 升序 | DESC 降序
 *
 * @return array;
 */
function arrayMultiSort(array $needArray, $field, $sort = 'ASC')
{
    $rule = [];
    $arrSort = [];

    $sort = strtoupper($sort);
    $rule['direction'] = 'SORT_' . $sort;
    $rule['field'] = $field;

    foreach ($needArray AS $uniqid => $row) {
        foreach ($row AS $key => $value) {
            $arrSort[$key][$uniqid] = $value;
        }
    }
    if ($rule['direction']) {
        array_multisort($arrSort[$rule['field']], constant($rule['direction']), $needArray);
    }

    return $needArray;
}

/**
 * 利用firephp输出调试到header
 *
 * 需要安装:
 * firefox:FireBug | chrome:FirePHP for Chrome
 *
 * @param mixed $message 要输出的信息
 * @param bool $showtime 是否显示执行时间
 */
function console($message, $showtime = false)
{
    static $lasttime = TIME;
    static $_getInstance;

    $thistime = microtime(true);
    $usedtime = $thistime - $lasttime;
    $lasttime = $thistime;

    $label = $showtime ? sprintf("%09.5fs", $usedtime) : NULL;

    if (is_null($_getInstance)) {
        $_getInstance = \Mall\Framework\Core\FirePHP::getInstance(true);
    }

    $_getInstance->info($message, $label);
}

/**
 * 检测数组的值不允许为空
 *
 * @param array $params 需要检测的数组
 * @param array $checkKey 需要检测的key默认全部检测
 * @param array $excludeKey 过虑不检测的Key
 *
 * @return string
 */
function checkNotEmpty($params, $excludeKey = [], $checkKey = [])
{
    $newParams = [];
    if ($checkKey && is_array($checkKey)) {
        foreach ($checkKey as $key) {
            if (isset($params[$key])) {
                $newParams[$key] = $params[$key];
            }
        }
    }

    if ($newParams) {
        $params = $newParams;
    }

    if (is_array($params)) {
        foreach ($params as $k => $v) {
            if (in_array($k, $excludeKey, true)) {
                continue;
            }

            if (is_array($v)) {
                checkNotEmpty($v);
            }

            if (empty($v)) {
                return $k . ' 不允许为空';
            }
        }
    }
}

/**
 * 友好格式化时间
 * @param int $timestamp 时间
 * @param array $formats
 * @return string
 */
function formatDateTime($timestamp, $formats = null)
{
    if ($formats == null) {
        $formats = array(
            'DAY'           => '%s天前',
            'DAY_HOUR'      => '%s天%s小时前',
            'HOUR'          => '%s小时',
            'HOUR_MINUTE'   => '%s小时%s分前',
            'MINUTE'        => '%s分钟前',
            'MINUTE_SECOND' => '%s分钟%s秒前',
            'SECOND'        => '%s秒前',
        );
    }

    /* 计算出时间差 */
    $seconds = time() - $timestamp;
    $minutes = floor($seconds / 60);
    $hours = floor($minutes / 60);
    $days = floor($hours / 24);
    if ($days > 0 && $days < 31) {
        $diffFormat = 'DAY';
    } elseif ($days == 0) {
        $diffFormat = ($hours > 0) ? 'HOUR' : 'MINUTE';
        if ($diffFormat == 'HOUR') {
            $diffFormat .= ($minutes > 0 && ($minutes - $hours * 60) > 0) ? '_MINUTE' : '';
        } else {
            $diffFormat = (($seconds - $minutes * 60) > 0 && $minutes > 0)
                ? $diffFormat . '_SECOND' : 'SECOND';
        }
    } else {
        $diffFormat = 'TURE_DATE_TIME';//超出30天, 正常时间显示
    }

    $dateDiff = null;
    switch ($diffFormat) {
        case 'DAY':
            $dateDiff = sprintf($formats[$diffFormat], $days);
            break;
        case 'DAY_HOUR':
            $dateDiff = sprintf($formats[$diffFormat], $days, $hours - $days * 60);
            break;
        case 'HOUR':
            $dateDiff = sprintf($formats[$diffFormat], $hours);
            break;
        case 'HOUR_MINUTE':
            $dateDiff = sprintf($formats[$diffFormat], $hours, $minutes - $hours * 60);
            break;
        case 'MINUTE':
            $dateDiff = sprintf($formats[$diffFormat], $minutes);
            break;
        case 'MINUTE_SECOND':
            $dateDiff = sprintf($formats[$diffFormat], $minutes, $seconds - $minutes * 60);
            break;
        case 'SECOND':
            $dateDiff = sprintf($formats[$diffFormat], $seconds);
            break;
        default:
            $dateDiff = date('Y-m-d H:i:s',$timestamp);
    }
    return $dateDiff;
}

/**
 * 数组交叉排序并合并
 *
 * @param array $needo
 * @param array $needt
 *
 * @return array
 */
function sortCross(array $needo = [], array $needt = [])
{
    $newData = [];
    $needoCount = count($needo);
    $needtCount = count($needt);
    $size = $needoCount > $needtCount ? $needoCount : $needtCount;

    for ($i = 0; $i < $size; $i++) {
        if (isset($needo[$i])) {
            array_push($newData, $needo[$i]);
        }
        if (isset($needt[$i])) {
            array_push($newData, $needt[$i]);
        }
    }

    return $newData;
}

/**
 * 二维数组去重
 *
 * @param $list
 * @param $key
 *
 * @return array
 */
function assocUnique($list, $key)
{
    $arr = array();
    for ($i = 0; $i < count($list); $i++) {
        if (isset($list[$i][$key])) {
            if (!isset($arr[$list[$i][$key]])) {
                $arr[$list[$i][$key]] = $list[$i];
            }
        }
    }
    return array_values($arr);
}

/**
 * 为相对路径的缩略图加绝对地址
 *
 * @param string|array $thumbs 图片集合
 * @param string $key 图片地址的Key
 *
 * @return array
 */
function absoluteImg($thumbs, $key = '')
{
    if ($thumbs) {
        if (is_array($thumbs)) {
            foreach ($thumbs as &$t) {
                if ($key) {
                    $value = $t[$key];
                } else {
                    $value = $t;
                }
                if (!$value) {
                    continue;
                }
                if (!filter_var($value, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) {
                    if ($key) {
                        $t[$key] = URL_UPLOAD . $value;
                    } else {
                        $t = URL_UPLOAD . $value;
                    }
                }
            }
        }

        if (is_string($thumbs)) {
            if (!filter_var($thumbs, FILTER_VALIDATE_URL, FILTER_FLAG_HOST_REQUIRED)) {
                $thumbs = URL_UPLOAD . $thumbs;
            }
        }
    }

    return $thumbs;
}

/**
 * 对内容字段进行 int 整形转换
 *
 * @param array $params
 *
 * @return array
 */
function contentIntValFormat(array $params)
{
    $intVal = [
        'id',
        'appid',
        'has_thumb',
        'catid',
        'created',
        'createdby',
        'published',
        'publishedby',
        'modified',
        'modifiedby',
        'digg',
        'pv',
        'virtual_pv',
        'status',
        'indexid',
        'contentid',
        'pagecount',
        'weight',
        'commend',
        'noexpiration',
        'commend_pv',
        'iscount'
    ];
    foreach ($params as $k => $param) {
        if (in_array($k, $intVal, true)) {
            $params[$k] = intval($param);
        }
    }

    return $params;
}

/**
 * 根据用户年月日算出星座
 *
 * @param string $dob 出生年月 1990-12-18
 *
 * @return string
 */
function constellation($dob)
{
    $dob = date("m-d", strtotime($dob));
    list($month, $day) = explode("-", $dob);

    $constellation = '';
    if (($month == 3 || $month == 4) && ($day > 22 || $day < 21)) {
        $constellation = "Aries";
    } else if (($month == 4 || $month == 5) && ($day > 22 || $day < 22)) {
        $constellation = "Taurus";
    } else if (($month == 5 || $month == 6) && ($day > 23 || $day < 22)) {
        $constellation = "Gemini";
    } else if (($month == 6 || $month == 7) && ($day > 23 || $day < 23)) {
        $constellation = "Cancer";
    } else if (($month == 7 || $month == 8) && ($day > 24 || $day < 22)) {
        $constellation = "Leo";
    } else if (($month == 8 || $month == 9) && ($day > 23 || $day < 24)) {
        $constellation = "Virgo";
    } elseif (($month == 9 || $month == 10) && ($day > 25 || $day < 24)) {
        $constellation = "Libra";
    } else if (($month == 10 || $month == 11) && ($day > 25 || $day < 23)) {
        $constellation = "Scorpio";
    } else if (($month == 11 || $month == 12) && ($day > 24 || $day < 23)) {
        $constellation = "Sagittarius";
    } else if (($month == 12 || $month == 1) && ($day > 24 || $day < 21)) {
        $constellation = "Cpricorn";
    } else if (($month == 1 || $month == 2) && ($day > 22 || $day < 20)) {
        $constellation = "Aquarius";
    } else if (($month == 2 || $month == 3) && ($day > 21 || $day < 21)) {
        $constellation = "Pisces";
    }

    return $constellation;
}

/**
 * 随机生成短信验证码
 * @param int $length 验证码长度
 * @return int
 */
function generate_code($length = 6)
{
    return rand(pow(10, ($length - 1)), pow(10, $length) - 1);
}

/**
 * 计算两点地理坐标之间的距离
 * @param  string $longitude1 起点经度
 * @param  string $latitude1 起点纬度
 * @param  string $longitude2 终点经度
 * @param  string $latitude2 终点纬度
 * @param  int $unit 单位 1:米 2:公里
 * @param  int $decimal 精度 保留小数位数
 * @return string
 */
function getDistance($longitude1, $latitude1, $longitude2, $latitude2, $unit = 2, $decimal = 2)
{

    $EARTH_RADIUS = 6370.996; // 地球半径系数
    $PI = 3.1415926;

    $radLat1 = $latitude1 * $PI / 180.0;
    $radLat2 = $latitude2 * $PI / 180.0;

    $radLng1 = $longitude1 * $PI / 180.0;
    $radLng2 = $longitude2 * $PI / 180.0;

    $a = $radLat1 - $radLat2;
    $b = $radLng1 - $radLng2;

    $distance = 2 * asin(sqrt(pow(sin($a / 2), 2) + cos($radLat1) * cos($radLat2) * pow(sin($b / 2), 2)));
    $distance = $distance * $EARTH_RADIUS * 1000;

    if ($unit == 2) {
        $distance = $distance / 1000;
    }

    return round($distance, $decimal);

}

/**
 * @param int $month 月份
 * @param int $year 年
 *
 * @return mixed
 */
function getMonthBeginToEnd($month, $year = 0)
{
    $beginDate = 0;
    $endDate = 0;

    if ($month = intval($month)) {
        if (!$year) {
            $year = date('Y', time());
        }

        $beginDate = strtotime("{$year}-{$month}-01");
        $endDate = strtotime(date('Y-m-t', $beginDate));
    }

    return [
        'beginTime' => $beginDate,
        'endTime'   => $endDate
    ];
}

/**
 * 格式化商品价格
 *
 * @access  public
 * @param   float $price 商品价格
 * @return  string
 */
function priceFormat($price)
{
    return number_format($price, 2, '.', '');
}

/**
 * 数组转xml内容
 *
 * @param   array $arr 数组
 * @return  string
 */
function arrayToXml($arr)
{
    $xml = '';
    foreach ($arr as $key => $value) {
        if (is_string($value)) {
            $xml .= '<' . $key . '>';
        } else {
            $xml .= '<' . $key . '>' . $value . '';
        }
    }
    return $xml;
}

//数组转xml
function arrayToWeiXinXml($arr)
{
    $xml = '';
    foreach($arr as $key => $value){
        if (is_string($value)) {
            $xml .= '<' . $key . '>';
        } else {
            $xml .= '<' . $key . '>' . $value . '';
        }
    }
    $xml .='';
    return $xml;
}

/**
 * xml转json格式数据
 *
 * @param string $xml xml格式文件内容
 * @return string
 */
function XML2JSON($xml)
{

    function normalizeSimpleXML($obj, &$result)
    {
        $data = $obj;
        if (is_object($data)) {
            $data = get_object_vars($data);
        }
        if (is_array($data)) {
            foreach ($data as $key => $value) {
                $res = null;
                normalizeSimpleXML($value, $res);
                if (($key == '@attributes') && ($key)) {
                    $result = $res;
                } else {
                    $result[$key] = $res;
                }
            }
        } else {
            $result = $data;
        }
    }

    normalizeSimpleXML(simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOCDATA), $result);
    return json_encode($result, JSON_UNESCAPED_UNICODE);
}

/**
 * 分页方法
 */
function pageToOffset($page = 1, $pageSize = 10)
{
    return [
        'limit'  => $pageSize,
        'offset' => ($page - 1) * $pageSize,
    ];
}

/**
 * PHP截取UTF-8字符串,解决半字符问题。
 * 英文、数字(半角)为1字节(8位),中文(全角)为2字节
 * 取出的字符串, 当$len小于等于0时, 会返回整个字符串
 * @param string $str 源字符串
 * @param int $len 左边的子串的长度
 */
function utf_substr($str, $len)
{
    $new_str = [];
    for ($i = 0; $i < $len; $i++) {
        $temp_str = substr($str, 0, 1);
        if (ord($temp_str) > 127) {
            if ($i < $len) {
                $new_str[] = substr($str, 0, 3);
                $str = substr($str, 3);
            }
        } else {
            $new_str[] = substr($str, 0, 1);
            $str = substr($str, 1);
        }
    }
    return join($new_str);
}


function isCardNo($vStr)
{
    $vCity = array(
        '11', '12', '13', '14', '15', '21', '22',
        '23', '31', '32', '33', '34', '35', '36',
        '37', '41', '42', '43', '44', '45', '46',
        '50', '51', '52', '53', '54', '61', '62',
        '63', '64', '65', '71', '81', '82', '91'
    );
    if (!preg_match('/^([\d]{17}[xX\d]|[\d]{15})$/', $vStr)) return false;
    if (!in_array(substr($vStr, 0, 2), $vCity)) return false;
    $vStr = preg_replace('/[xX]$/i', 'a', $vStr);
    $vLength = strlen($vStr);
    if ($vLength == 18) {
        $vBirthday = substr($vStr, 6, 4) . '-' . substr($vStr, 10, 2) . '-' . substr($vStr, 12, 2);
    } else {
        $vBirthday = '19' . substr($vStr, 6, 2) . '-' . substr($vStr, 8, 2) . '-' . substr($vStr, 10, 2);
    }
    if (date('Y-m-d', strtotime($vBirthday)) != $vBirthday) return false;
    if ($vLength == 18) {
        $vSum = 0;
        for ($i = 17; $i >= 0; $i--) {
            $vSubStr = substr($vStr, 17 - $i, 1);
            $vSum += (pow(2, $i) % 11) * (($vSubStr == 'a') ? 10 : intval($vSubStr, 11));
        }
        if ($vSum % 11 != 1) return false;
    }
    return true;
}

/**
 * try_catch 统一写入日志方法
 * @param object $logger Factory::logs
 * @param $exception  捕获的异常内容
 */
function catchError($logger, $exception)
{
    $error = '错误类型:' . get_class($exception) . PHP_EOL;
    $error .= '错误代码:' . $exception->getCode() . PHP_EOL;
    $error .= '错误信息:' . $exception->getMessage() . PHP_EOL;
    $error .= '错误堆栈:' . $exception->getTraceAsString() . PHP_EOL;

    $logger && $logger->log($error, 'error');
}

/**
 * 资金元单位转化为分单位
 * @param float 元
 * @return int 分
 */
function yuanToFen($yuan)
{
    $fen = strval($yuan * 100);
    return intval($fen);
}

/**
 * 资金分单位转化为元单位
 * @param int 分
 * @return float 元
 */
function fenToYuan($fen)
{
    $fen = $fen / 100;
    return $fen;
}


/**
 * 千克转为克
 * @param string|float
 * @return int
 */
function kgTog($kg)
{
    $g = strval($kg * 1000);
    return $g = intval($g);
}


/**
 * 克转为千克
 * @param string|float
 * @return int
 */

function gToKg($kg)
{
    $kg = $kg / 1000;
    return $kg;
}


/**
 * 元/千克 转为 分/克 并保留8位有效数字
 * @param string|float
 * @return int
 */
function kgYuanTogFenDanWei($KgYuan)
{
    $gFen = $KgYuan / 10;
    return $gFen;
}

function floatDiv($param)
{
    return $param / 100000000;
}

function floatMul($param)
{
    return $param * 100000000;
}


/**
 * 分/克 转为 元/千克
 * @param string|float
 * @return int
 */
function gFenToKgYuanDanWei($gFen)
{
    $kgYuan = $gFen * 10;
    return $kgYuan;
}

/**
 * 获取当前的时间(毫秒)
 * @return float
 */
function getMillisecond()
{
    list($t1, $t2) = explode(' ', microtime());
    return (float)sprintf('%.0f', (floatval($t1) + floatval($t2)) * 1000);
}


/**
 * 多维数组转树状结构
 *
 * @param $tree
 * @param int $rootId
 * @return array
 */
function arr2tree($tree, $rootId = 0)
{

    $return = [];
    foreach ($tree as $leaf) {
        if ($leaf['pid'] == $rootId) {
            foreach ($tree as $subleaf) {
                if ($subleaf['pid'] == $leaf['id']) {
                    $leaf['children'] = arr2tree($tree, $leaf['id']);
                    break;
                }
            }
            $return[] = $leaf;
        }
    }

    return $return;
}

/**
 * <生成订单号>
 * 规则说明: 来源(pc/ios/android)1位 + 订单类型标示(海淘/门票)1位 + 时间戳转日期(20171107)8位 + 用户id(2位) + 毫秒时间提取(4位)
 * @param $orderFrom
 * @param $orderTypeId
 * @param $userId
 * @return int
 */
function createOrderSn($orderFrom, $orderTypeId, $userId)
{
    $no = $orderFrom . $orderTypeId . date('Ymd') . substr(strval($userId + 100), -2) . substr(microtime(), 2, 4) . sprintf('%02d', rand(1000, 9999));

    return $no;
}

/**
 * 按照日期生成流水号
 * @param string $maxNo 当天最后一条数据编号
 */
function createSerialNumberByDate($maxNo = '',$dateLength = 8, $lenght = 4)
{
    $number = 0;
    if( !empty($maxNo) ){
        $todayLastNo = explode('-',$maxNo);
        $number = intval($todayLastNo[1]);
    }
    $number = $number+1;
    switch ($dateLength){
        case 12: // 根据年月日时分生成流水号
            $date = date('YmdHi',time());
            break;
        case 14: // 根据年月日时分秒生成流水号
            $date = date('YmdHis',time());
            break;
        default: // 根据年月日生成流水号
            $date = date('Ymd',time());
    }

    return $date.'-'.str_pad($number,$lenght,'0',STR_PAD_LEFT);
}

/**
 * 生成编码
 * @param $prefix 编码前缀 例如:采购入库单 CGRK
 * @param $id 自动id
 * @param int $length 编码长度
 * @return string
 */
function createCode($prefix, $id, $length = 6)
{
    $idLength = strlen((string)$id);
    $leaveLength = $length - $idLength;
    $zeroStr = "";
    if ($leaveLength > 0) {
        $zeroStr = str_repeat('0', $leaveLength);
    }
    return strtoupper($prefix) . $zeroStr . $id;
}

/**
 * 随机生成16位字符串
 * @return string 生成的字符串
 */
function getRandomStr($lenght = 16)
{

    $str = "";
    $str_pol = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz";
    $max = strlen($str_pol) - 1;
    for ($i = 0; $i < $lenght; $i++) {
        $str .= $str_pol[mt_rand(0, $max)];
    }
    return $str;
}


/*
 * uuid 唯一序列码
 */

function uuid($prefix = '')
{
    $chars = md5(uniqid(mt_rand(), true));
    $uuid  = substr($chars,0,8) . '-';
    $uuid .= substr($chars,8,4) . '-';
    $uuid .= substr($chars,12,4) . '-';
    $uuid .= substr($chars,16,4) . '-';
    $uuid .= substr($chars,20,12);
    return $prefix . $uuid;
}

/**
 * 获取 当天,昨天,本周,本月,本年时间戳
 */

function gettimestamp($name = 'today',$param = ''){
    switch ($name){
        case 'today'://今天
            $timeamp['start'] = strtotime(date('Y-m-d'));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
            break;
        case 'yesterday'://昨天
            $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-1 day')));
            $timeamp['end'] = strtotime(date('Y-m-d'));
            break;
        case 'beforyesterday'://前天
            $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-2 day')));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('-1 day')));
            break;
        case 'beforweek'://本周
            $timeamp['start'] = strtotime(date("Y-m-d H:i:s",mktime(0, 0 , 0,date("m"),date("d")-date("w")+1,date("Y"))));
            $timeamp['end'] = strtotime(date("Y-m-d H:i:s",mktime(23,59,59,date("m"),date("d")-date("w")+7,date("Y"))));
            break;
        case 'nowmonth'://本月
            $timeamp['start'] = strtotime(date('Y-m-01'));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
            break;
        case 'permonth'://上月
            $timeamp['start'] = strtotime(date('Y-m-01',strtotime('-1 month')));
            $timeamp['end'] = strtotime(date('Y-m-01'));
            break;
        case 'preweek'://上周 注意我们是从周一开始算
            $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-2 week Monday')));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('-1 week Monday +1 day')));
            break;
        case 'nowweek'://本周
            $timeamp['start'] = strtotime(date('Y-m-d',strtotime('-1 week Monday')));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
            break;
        case 'preday'://近三个月
//            $timeamp['start'] = strtotime(date('Y-m-d'),strtotime($param.' day'));
            $timeamp['start'] = strtotime("-0 year -3 month -0 day");
            $timeamp['end'] = strtotime(date('Y-m-d'));
            break;
        case 'nextday'://30
            $timeamp['start'] = strtotime(date('Y-m-d'));
            $timeamp['end'] = strtotime(date('Y-m-d'),strtotime($param.' day'));
            break;
        case 'preyear'://去年
            $timeamp['start'] = strtotime(date('Y-01-01',strtotime('-1 year')));
            $timeamp['end'] = strtotime(date('Y-12-31',strtotime('-1 year')));
            break;
        case 'nowyear'://今年
            $timeamp['start'] = strtotime(date('Y-01-01'));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
            break;
        case 'quarter'://季度
            $quarter = empty($param) ? ceil((date('n'))/3) : $param;//获取当前季度
            $timeamp['start'] = mktime(0, 0, 0,$quarter*3-2,1,date('Y'));
            $timeamp['end'] = mktime(0, 0, 0,$quarter*3+1,1,date('Y'));
//            $timeamp['end'] = mktime(23,59,59,$quarter*3,date('t',mktime(0, 0 , 0,$quarter*3,1,date("Y"))),date('Y'));
            break;
        default:
            $timeamp['start'] = strtotime(date('Y-m-d'));
            $timeamp['end'] = strtotime(date('Y-m-d',strtotime('+1 day')));
            break;
    }
    return $timeamp;
}