<?php
/**
 * 常用工具库
 */
namespace util;

class Util {

    /**
     * 获取来访IP
     * @return string
     */
    public static function getIp(){
        $ip = null;
        if (getenv('HTTP_CLIENT_IP') && strcasecmp(getenv('HTTP_CLIENT_IP'), 'unknown')){
            $ip = getenv('HTTP_CLIENT_IP');
        } elseif (getenv('HTTP_X_FORWARDED_FOR') && strcasecmp(getenv('HTTP_X_FORWARDED_FOR'), 'unknown')){
            $ip = getenv('HTTP_X_FORWARDED_FOR');
        } elseif (getenv('REMOTE_ADDR') && strcasecmp(getenv('REMOTE_ADDR'), 'unknown')){
            $ip = getenv('REMOTE_ADDR');
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'],'unknown')){
            $ip = $_SERVER['REMOTE_ADDR'];
        }else{
            $ip = '0.0.0.0';
        }
        //是否是一个合法的ip地址
        return (false !== ip2long($ip)) ? $ip : '0.0.0.0';
    }

    /**
     * 返回IP的整数形式
     *
     * @param string $ip
     * @return string
     */
    public static function getLongIp($ip = ''){
        if ($ip == '') {
            $ip = self::getIp();
        }
        return sprintf("%u", ip2long($ip));
    }

    /**
     * 获取字符串长度
     * @param string $str 字符串
     * @param int $zhLen 中文字符长度
     * @return int
     */
    public static function getStrLen($str, $zhLen = 0){
        if ($zhLen == 0) {
            return strlen($str);
        } else {
            $match = [];
            preg_match_all("/./us", $str, $match);
            $count = 0;
            foreach ($match[0] as $v) {
                $count += (strlen($v) == 1) ? 1 : $zhLen;
            }
            return $count;
        }
    }

    /**
     * 中英文字符串截取
     * @param  string  $str     字符串
     * @param  integer $start   起始长度
     * @param  integer $length  截取长度
     * @param  string  $charset 字符编码
     * @param  boolean $suffix  截取后缀
     * @return string
     */
    public static function msubstr($str, $start = 0, $length, $charset="utf-8", $suffix = true){
        if($charset!='utf-8'){
            $str = mb_convert_encoding($str,'utf8',$charset);
        }
        $osLen = mb_strlen($str);
        if($osLen <= $length){
            return $str;
        }
        $string = mb_substr($str,$start,$length,'utf8');
        $sLen = mb_strlen($string,'utf8');
        $bLen = strlen($string);
        $sCharCount = (3*$sLen-$bLen)/2;
        if($osLen<=$sCharCount+$length){
            $arr = preg_split('/(?<!^)(?!$)/u',mb_substr($str,$length+1,$osLen,'utf8')); //将中英混合字符串分割成数组（UTF8下有效）
        }else {
            $arr = preg_split('/(?<!^)(?!$)/u',mb_substr($str,$length+1,$sCharCount,'utf8'));
        }
        foreach($arr as $value){
            if(ord($value)<128 && ord($value)>0){
                $sCharCount = $sCharCount-1;
            }else {
                $sCharCount = $sCharCount-2;
            }
            if($sCharCount<=0){
                break;
            }
            $string.=$value;
        }
        if($suffix) return $string."…";
        return $string;
    }

    /**
     * 判断UTF-8
     * @param  string  $string 字符串
     * @return boolean
     */
    public static function isUtf8($string){
        if( !empty($string) ) {
            $ret = json_encode( array('code'=>$string) );
            if( $ret=='{"code":null}') {
                return false;
            }
        }
        return true;
    }

    /**
     * 字符串转码
     * @param  string $fContents 字符串
     * @param  string $from      原始编码
     * @param  string $to        目标编码
     * @return string
     */
    public static function auto_charset($fContents,$from='gbk',$to='utf-8'){
        $from   =  strtoupper($from)=='UTF8'? 'utf-8':$from;
        $to       =  strtoupper($to)=='UTF8'? 'utf-8':$to;
        if( strtoupper($from) === strtoupper($to) || empty($fContents) || (is_scalar($fContents) && !is_string($fContents)) ){
            //如果编码相同或者非字符串标量则不转换
            return $fContents;
        }
        if(is_string($fContents) ) {
            if(function_exists('mb_convert_encoding')){
                return mb_convert_encoding ($fContents, $to, $from);
            }elseif(function_exists('iconv')){
                return iconv($from,$to,$fContents);
            }else{
                return $fContents;
            }
        }
        elseif(is_array($fContents)){
            foreach ( $fContents as $key => $val ) {
                $_key =     self::auto_charset($key,$from,$to);
                $fContents[$_key] = self::auto_charset($val,$from,$to);
                if($key != $_key )
                    unset($fContents[$key]);
            }
            return $fContents;
        }
        else{
            return $fContents;
        }
    }

     /**
     * 显示友好时间格式
     * @param int $time 时间戳
     * @param string $format
     * @param int $start_time
     * @param string $suffix
     * @return string
     */
    public static function ftime($time, $format = 'Y-m-d H:i:s', $start_time = 0, $suffix = '前'){
        if ($start_time == 0) {
            $start_time = time();
        }
        $t = $start_time - $time;
        if ($t < 63072000) {
            $f = array(
                '31536000' => '年',
                '2592000' => '个月',
                '604800' => '星期',
                '86400' => '天',
                '3600' => '小时',
                '60' => '分钟',
                '1' => '秒'
            );
            foreach ($f as $k => $v) {
                if (0 != $c = floor($t / (int)$k)) {
                    return $c . $v . $suffix;
                }
            }
        }
        return date($format, $time);
    }

    /**
     * 格式化数据大小(单位byte)
     *
     * @param int $size
     * @return string
     */
    public static function convert($size){
        $unit = array('b', 'kb', 'mb', 'gb', 'tb', 'pb');
        $s = floor(log($size, 1024));
        $i = (int)$s;

        if (isset($unit[$i])) {
            return sprintf('%.2f ' . $unit[$i], $size / pow(1024, $s));
        }
        return $size . ' ' . $unit[0];
    }

    /**
     * 取得文件扩展名
     *
     * @param string $file 文件名
     * @return string
     */
    public static function getExt($file){
        $file_info = pathinfo($file);
        return $file_info['extension'];
    }

    /**
     * html转换字符串
     * @param  string $field 字段名/HTML内容
     * @param  type   $type 字段类型
     * @return string
     */
    public static function htmlEncode($data){
        return htmlspecialchars($data, ENT_QUOTES, 'UTF-8');
    }

    /**
     * 字符串转换html
     * @param  string $field 字段名/HTML内容
     * @param  type   $type 字段类型
     * @return string
     */
    public static function htmlDecode($data){
        return htmlspecialchars_decode(html_entity_decode($data, ENT_QUOTES, 'UTF-8'));
    }

    /**
     * 判断是否为HTTPS请求
     * @return bool
     */
    public static function isHttps(){
        $https = isset($_SERVER["HTTPS"]) ? $_SERVER["HTTPS"] : "";
        if (strtolower($https) == "on") {
            return true;
        }
        $https = isset($_SERVER["HTTP_X_FORWARDED_PROTO"]) ? $_SERVER["HTTP_X_FORWARDED_PROTO"] : "";
        if (strtolower($https) == "https") {
            return true;
        }
        return false;
    }

    /**
     * 获取当前网址
     * @return string
     */
    public static function getCurrentUrl($is_request = false){
        $http_host = self::isHttps() ? "https://" : "http://".$_SERVER["HTTP_HOST"];
        if($is_request){
            $http_host = $http_host.$_SERVER["REQUEST_URI"];
        }
        return filter_var($http_host,FILTER_VALIDATE_URL,FILTER_FLAG_HOST_REQUIRED);
    }

    /**
     * 函数通过千位分组来格式化数字。
     * @param [type] $str
     * @return void
     */
    public static function priceFormat($str) {
        if (empty($str)) {
            return $str = 0;
        }
        return @number_format($str, 2, ".", ",");
    }
 
    /**
     * 创建文件夹
     * @param string $path
     * @param int $mode
     */
    public static function mkdir($path, $mode = 0777){
        if(is_dir($path)){
            return true;
        }
        try {
            mkdir($path,$mode,true);
        }catch (\Exception $e) {
            return false;
        }
        return true;
    }

      /**
     * 创建文件
     * @param string $path
     * @param int $mode
     */
    public static function mkfile($path,$filecontent){
        try {
            $file = fopen($path,"w");
            fwrite($file,$filecontent);
            fclose($file);
            return true;
        }catch (\Exception $e) {
            return false;
        }
    }  

    /**
     * newResponseData 下载证书接口返回数据对比后最新的一次响应数据
     * @param $key
     * @param $data
     */
    public static function file_body(string $path,string $body = ''){
        self::mkdir(dirname($path));
        if(empty($body)){
            if (file_exists($path)){
                return file_get_contents($path);
            }
        }else{
            if (file_put_contents($path,$body)) {
                return file_get_contents($path);
            }
        }
        return false;
    }

    /**
     * 两个任意精度的数字计算
     *
     * @param [type] $n1  计算数字一
     * @param [type] $symbol 计算方式
     * @param [type] $n2  计算数字二
     * @param string $scale 精度
     * @return void
     */
    public static function priceCalculate($n1, $symbol, $n2, $scale = '2') {
        switch ($symbol) {
            case "+"://加法
                $res = bcadd($n1, $n2, $scale);
                break;
            case "-"://减法
                $res = bcsub($n1, $n2, $scale);
                break;
            case "*"://乘法
                $res = bcmul($n1, $n2, $scale);
                break;
            case "/"://除法
                $res = bcdiv($n1, $n2, $scale);
                break;
            case "%"://求余、取模
                $res = bcmod($n1, $n2, $scale);
                break;
            default:
                $res = 0;
                break;
        }

        return $res;
    }

	/**
	 * 方法库-数组去除空值
	 * @param string $arr  数组
	 * @return array
	 */
	public static function array_remove_empty($arr, $trim = true) {
        if (!is_array($arr)){
            return false;
        }
		foreach($arr as $key => $value){
			if (is_array($value)) {
				self::array_remove_empty($arr[$key]);
			} else {
				$value = ($trim == true) ? trim($value) : $value;
				if ($value == "") {
					unset($arr[$key]);
				} else {
					$arr[$key] = $value;
				}
			}
        }
        return $arr;
    }
    
    /**
     * 多维数组删除相同的数组组合
     * @param  array $arr  要删除的数组
     * @return array
     */
    public static function unique_array($arr){
        foreach ($arr as $k => $v) {
            $arr[$k] = serialize($v);
        }
        $arr = array_unique($arr);
        foreach ($arr as $k => $v) {
            $arr[$k] = unserialize($v);
        }
        return $arr;
    }
}