<?php
/**
 * Notes:通用方法
 * User: wsc
 * Time: 2020/3/11 19:43
 * Class funs
 */

class funs
{
    /**
     * Notes:获取概率id
     * User: wsc
     * Time: 2020/3/12 11:28
     * @param $proArr ["id"=>"权重",...]
     * @return int|string
     */
    static function get_randByProb($proArr){
        $result = '';
        foreach ($proArr as $k=>$v){
            $proArr[$k]=intval($v*100);
        }
        //概率数组的总概率精度
        $proSum = array_sum($proArr);
        //概率数组循环
        foreach ($proArr as $key => $proCur) {
            $randNum = mt_rand(1, $proSum);
            if ($randNum <= $proCur) {
                $result = $key;
                break;
            } else {
                $proSum -= $proCur;
            }
        }
        unset ($proArr);
        return $result;
    }

    /**
     * Notes:单位换算(不支持浮点带单位输出)
     * User: wsc
     * Time: 2020/3/12 12:06
     * @param $str int|string  要换算的，数组字串
     * @param string $units 单位
     * @return bool|int|string （浮点带单位输出false）
     */
    static function  units_conversion($str,$units = 'int'){
        if(empty($str)||0==$str) return false;
        $u_arr = ['k'=>1000,'w'=>10000,'m'=>1000000];
        $uk_arr = array_keys($u_arr);
        $str_unit = substr($str,-1);//传入字串单位
        $num = in_array($str_unit,$uk_arr)?intval($u_arr[$str_unit]*intval($str)):intval($str);
        $res = $units!='int'&&in_array($units,$uk_arr)?($num%$u_arr[$units]===0?intval($num/$u_arr[$units]).$units:false):intval($num);
        return $res;
    }

    /**
     * Notes:数组键是json的解析
     * User: wsc
     * Time: 2020/3/25 16:19
     * @param $arr
     * @return array
     */
    static function getArrFromJsonArr($arr){
        if(empty($arr)||!is_array($arr)) return [];
        foreach ($arr as $k=>$v){
            $data[$k] = json_decode($v,true);
        }
        return $data;
    }

    static function getArrayFromOne($arr){
        if(is_string($arr)){
            $arr = self::analyJson($arr);
        }
        if(empty($arr)||!is_array($arr)) return [];
        foreach ($arr as $k=>$v){
            $data[$k] = self::analyJson($v);
        }
        return $data;
    }

    static function analyJson($json_str) {
//方法一
        $ret = json_decode($json_str,true);
        if(json_last_error() === JSON_ERROR_NONE){
            return $ret;
        }
        return $json_str;
//方法二
//        $result = $json_str;
//        $json_str = str_replace('\\', '', $json_str);
//        $out_arr = array();
//        preg_match('/{.*}/', $json_str, $out_arr);
//        if (!empty($out_arr)) {
//            $result = json_decode($out_arr[0], TRUE);
//            if(!is_array($result)){
//                $result = $json_str;
//            }
//        }
//        return $result;
    }

    static function enjson($code){
        $code = json_encode(self::urlencodeAry($code));
        return urldecode($code);
    }
    static function urlencodeAry($data){
        if(is_array($data)){
            foreach($data as $key=>$val){
                $data[$key] = self::urlencodeAry($val);
            }
            return $data;
        }
        else{
            return urlencode($data);
        }
    }
    // json换行符无法解析过滤换行符
    static function dejson($str){
        $str = str_replace("\\", '\\\\', $str);
        $str = str_replace("\r\n", '', $str);
        return json_decode($str, 1);
    }

    //============================================
    /**
     * Notes:设置并发锁
     * User: wsc
     * Time: 2020/4/21 12:30
     * @param $uid
     * @param $type
     * @param $time
     * @return bool 成功返回true,并发重复返回false
     */
    static function concurrentLock($uid,$type,$time = 2){
        $key = okeys::concurrentLock($uid,$type);
        $res = oo::commonOprRedis('common')->setnx($key,1);
        if($res){
            oo::commonOprRedis('common')->expire($key,$time);
            return true;
        }else{
            return false;
        }
    }

    /**
     * Notes:解锁
     * User: wsc
     * Time: 2020/4/21 12:30
     * @param $uid
     * @param $type
     */
    static function delConcurrentLock($uid,$type){
        $key = okeys::concurrentLock($uid,$type);
        oo::commonOprRedis('common')->delete($key);
    }

    /**
     * 检测倒计时锁
     * @param $uid
     * @param $type
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/17 9:51
     */
    static function checkCountdownLock($uid,$type){
        $res = oo::commonOprRedis('common')->ttl(okeys::countdownLock($uid,$type));
        if($res > 0){
            return $res;
        }else{
            return false;
        }
    }

    /**
     * 检测倒计时锁
     * @param $uid
     * @param $type
     * @param $value
     * @param $time
     * @return mixed
     * Created by: Owen
     * Created on: 2020/6/17 9:51
     */
    static function setCountdownLock($uid,$type,$value = 1,$time = 84600){
        $key = okeys::countdownLock($uid,$type);
        return oo::commonOprRedis('common')->setex($key,$value,$time);
    }

    /**
     * 删除倒计时锁
     * @param $uid
     * @param $type
     * @return int
     * Created by: Owen
     * Created on: 2020/7/16 11:04
     */
    static function delCountdownLock($uid,$type){
        return oo::commonOprRedis('common')->delete(okeys::countdownLock($uid,$type));
    }

    public static function get($s, $def = ''){
        $s = isset($_GET[$s]) ? $_GET[$s] : $_POST[$s];
        $s = isset($s) && $s != '' ? $s : $def;
        if($s && is_string($s)) $s = htmlspecialchars($s);
        return self::magic_quote($s);
    }

    public static function getPayload()
    {
        return json_decode(file_get_contents("php://input"),true);
    }
    /**
     * 根据magic_quote判断是否为变量添加斜杠
     * @param string $mixVar
     * @return string
     */
    public static function magic_quote( $mixVar ){
        if( !get_magic_quotes_gpc() ){
            return self::add_slashes($mixVar);
        }else{
            return $mixVar;
        }
    }
    /**
     * 使用反斜线引用字符串
     * @param string $mixVar
     * @return string
     */
    public static function add_slashes($mixVar){
        $temp = '';
        if( is_array($mixVar) ){
            foreach($mixVar as $key => $value){
                $temp[$key] = self::add_slashes($value);
            }
        }else{
            $temp = addslashes($mixVar);
        }
        return $temp;
    }


    /**
     * Notes:格式化 更新sql语句
     * @param $tb
     * @param $data
     * @param $w
     * @return string
     */
    public static function db_updateSQL($tb, $data, $w): string
    {
        $sql = "UPDATE {$tb} SET ";

        $arr = self::db_fieldAllow($data);
        foreach ($arr as $k => $v) {
            $sql .= "`$k`=$v,";
        }
        $sql = trim($sql, ',');
        $sql .= " WHERE {$w}";
        return $sql;
    }

    /**
     * Notes:格式化 插入sql语句
     * @param $tb
     * @param $data
     * @return string
     */
    public static function db_insertSQL($tb, $data): string
    {
        $arr = self::db_fieldAllow($data);

        $keys = array_keys($arr);
        $fields = '`' . implode('`, `', $keys) . '`';
        $values = implode(",", array_values($arr));
        return "INSERT INTO " . $tb . " ({$fields}) VALUES({$values})";
    }

    /**
     * Notes:批量写入
     * User: wsc
     * Time: 2020/12/24 10:42
     * @param $tb
     * @param $fieldArr array 字段
     * @param $dataArr  array 数据
     * @param int $dataArrIsJson int|bool 是否json数组
     * @return string
     */
    static function db_intsertArrSQL($tb,$fieldArr,$dataArr,$dataArrIsJson=0){
        foreach ($dataArr as $data){
            if($dataArrIsJson){
                $data = json_decode($data,true);
            }
            if(count($fieldArr)<count($data)){
                $n = count($data)-count($fieldArr);
                for ($i=$n;$i--;){
                    array_pop($data);
                }
            }else if(count($fieldArr)>count($data)){
                $n = count($fieldArr)-count($data);
                for ($i=$n;$i--;){
                    array_push($data,0);
                }
            }
            $value = "(";
            foreach ($data as $key=>$val){
                if(is_array($val)){
                    $val = json_encode($val);
                }
                $value .="'{$val}',";
            }
            $value = trim($value,',');
            $value .=")";
            $datas[] = $value;
        }
        $keys = array_values($fieldArr);
        $fields = '(`'.implode('`, `',$keys).'`)';
        $values = implode(',',$datas);
        $sql= "INSERT INTO {$tb} {$fields} VALUES {$values}";
        return $sql;
    }


    /**
     * Notes:批量写入,不考虑 array 顺序
     */
    static function db_intsertBatchSQLByKeys($tb,$dataArr,$dataArrIsJson=0){
        if (count($dataArr) < 1)return '';
        foreach ($dataArr as $data){
            if($dataArrIsJson){
                $data = json_decode($data,true);
            }
            $fieldsTmp = array_keys($data);
            sort($fieldsTmp);
            if (empty($fieldArr))$fieldArr = $fieldsTmp;
            else if($fieldsTmp != $fieldArr)return '';
            $value = "(";
            foreach ($fieldArr as $key){
                $val = $data[$key];
                if(is_array($val)){
                    $val = json_encode($val);
                }
                $value .="'{$val}',";
            }
            $value = trim($value,',');
            $value .=")";
            $datas[] = $value;

        }
        $keys = array_values($fieldArr);
        $fields = '(`'.implode('`, `',$keys).'`)';
        $values = implode(',',$datas);
        $sql= "INSERT INTO {$tb} {$fields} VALUES {$values}";
        return $sql;
    }

    /**
     * Notes:过滤非法字符
     * @param $data
     * @return array
     */
    public static function db_fieldAllow($data): array
    {
        $ret = [];
        foreach ($data as $key => $val) {
            if (preg_match('/^\(\w*(\+|\-|\*|\/)?\w*\)$/i', $val)) {
                // 支持在字段的值里面直接使用其它字段 ,例如 (score+1) (name) 必须包含括号
                $val = $val;
            } else{
                //将字符串中的单引号（'）、双引号（"）、反斜线（\）与 NUL（NULL 字符转义
                $val = "'" . addslashes($val) . "'";

            }
            $ret[$key] = $val;
        }
        return $ret;
    }

    /**
     * Notes:写库字段过滤验证
     * User: wsc
     * Time: 2020/5/15 16:03
     * @param $string
     * @return bool
     */
    public static function sqlFormat($string){
        if (empty($string))return false;
        $sensitive  = "insert|update|delete|..\/|.\/|union|into|load_file|outfile";
        $sen = explode('|', $sensitive);
        $ret = false;
        foreach ($sen as $v) {
            $pattern = '/' . $v . '/';
            preg_match($pattern, $string, $ret);
            if (!empty($ret)){
                return true;
            }
        }
        return false;
    }

    /**
     * Notes:管理后台参数过滤
     * User: wsc
     * Time: 2020/7/17 13:27
     * @param $param
     * @return mixed
     */
    public static function adminDateAllow($param){
        $arr =["frombg","mod","act","sid","lid","version"];
        foreach ($arr as $v){
            unset($param[$v]);
        }
        return $param;
    }

    /**
     * 获取IP
     * @return mixed|null
     * Created by: Owen
     * Created on: 2019/9/23 20:15
     */
    public static function getIp()
    {
        $ip = '';
        if ($_SERVER['HTTP_CLIENT_IP'] && strcasecmp($_SERVER['HTTP_CLIENT_IP'], 'unknown')) {
            $ip = $_SERVER['HTTP_CLIENT_IP'];
        } elseif ($_SERVER['HTTP_X_FORWARDED_FOR'] && strcasecmp($_SERVER['HTTP_X_FORWARDED_FOR'], 'unknown')) {
            $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
        } elseif (isset($_SERVER['REMOTE_ADDR']) && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        } elseif (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], 'unknown')) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ){
           return $ip;
        }
        if(filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) ){
            oo::logs()->debug3(['ip'=>$ip],'IPV6.log');
        }
        return null;
    }

    /**
     * Notes:获取用户国家信息合集
     * User: wsc
     * Time: 2020/5/21 18:31
     * @param $ip
     * @param int $type
     * @return array|string|null
     * @throws Exception
     */
    static function ip_info($ip,$type=1){
        $data = [];
        if(empty($ip)) return $data;
        switch ($type){
            case 1://本地IP库先查
                $info =  oo::ipAlg()->memorySearch($ip);
                if(!empty($info)&&is_string($info['region'])){//本地IP库先查
                    $country = oo::cfg('country');
                    $addressInfo = explode('|', $info['region']);
                    $data['country_code'] = $country[$addressInfo[0]];
                    if(empty($data['country_code'])){
                        oo::logs()->debug3(["type"=>1,"ip"=>$ip,"res"=>$info],'getIp');
                    }
                }else{
                    $data = self::ip_info2($ip);
                }
                break;
            case 2://www.geoplugin.net获取国家信息，频率每分钟120内
                $data = self::ip_info2($ip);
                break;
            case 3://887d.com获取国家信息，频率未知
                $data = self::ip_info3($ip);
                break;
            default:
                break;
        }
        return $data;
    }

    /**
     * 通过第三方获取Ip所在国家信息
     * @param null $ip
     * @param string $purpose
     * @param bool $deep_detect
     * @return array|null|string
     * @link https://www.geoplugin.com/examples
     */
    static function ip_info2($ip = NULL, $purpose = "location", $deep_detect = TRUE) {
        $output = NULL;
        if(empty($ip)||$ip=='') return [];
        if (filter_var($ip, FILTER_VALIDATE_IP) === FALSE) {
            $ip = $_SERVER["REMOTE_ADDR"];
            if ($deep_detect) {
                if (filter_var(@$_SERVER['HTTP_X_FORWARDED_FOR'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
                if (filter_var(@$_SERVER['HTTP_CLIENT_IP'], FILTER_VALIDATE_IP))
                    $ip = $_SERVER['HTTP_CLIENT_IP'];
            }
        }
        $purpose  = str_replace(array("name", "\n", "\t", " ", "-", "_"), NULL, strtolower(trim($purpose)));
        $support  = array("country", "countrycode", "state", "region", "city", "location", "address");
        $continents = array(
            "AF" => "Africa",
            "AN" => "Antarctica",
            "AS" => "Asia",
            "EU" => "Europe",
            "OC" => "Australia (Oceania)",
            "NA" => "North America",
            "SA" => "South America"
        );
        if (filter_var($ip, FILTER_VALIDATE_IP) && in_array($purpose, $support)) {
            $res = file_get_contents("http://www.geoplugin.net/json.gp?ip=" . $ip);
            $ipdat = @json_decode($res);
            if (@strlen(trim($ipdat->geoplugin_countryCode)) == 2) {
                switch ($purpose) {
                    case "location":
                        $output = array(
                            "city"      => @$ipdat->geoplugin_city,
                            "state"     => @$ipdat->geoplugin_regionName,
                            "country"    => @$ipdat->geoplugin_countryName,
                            "country_code"  => @$ipdat->geoplugin_countryCode,
                            "continent"   => @$continents[strtoupper($ipdat->geoplugin_continentCode)],
                            "continent_code" => @$ipdat->geoplugin_continentCode
                        );
                        break;
                    case "address":
                        $address = array($ipdat->geoplugin_countryName);
                        if (@strlen($ipdat->geoplugin_regionName) >= 1)
                            $address[] = $ipdat->geoplugin_regionName;
                        if (@strlen($ipdat->geoplugin_city) >= 1)
                            $address[] = $ipdat->geoplugin_city;
                        $output = implode(", ", array_reverse($address));
                        break;
                    case "city":
                        $output = @$ipdat->geoplugin_city;
                        break;
                    case "state":
                        $output = @$ipdat->geoplugin_regionName;
                        break;
                    case "region":
                        $output = @$ipdat->geoplugin_regionName;
                        break;
                    case "country":
                        $output = @$ipdat->geoplugin_countryName;
                        break;
                    case "countrycode":
                        $output = @$ipdat->geoplugin_countryCode;
                        break;
                }
            }else{
                oo::logs()->debug3(["type"=>2,"ip"=>$ip,"res"=>$res],'getIp');
                $output = self::ip_info3($ip);
            }
        }
        return $output;
    }

    /**
     * Notes:获取国家简称（备用）
     * User: wsc
     * Time: 2020/5/19 16:12
     * @param $ip
     * @param int $limit 复用次数
     * @return array|null
     * @link https://887d.com
     */
    static function ip_info3($ip,$limit=1){
        $data = [];
        $url = "https://887d.com/api/ip?q={$ip}";
        $res = self::sendCurl($url);
        if(@strlen(trim($res)) == 2){
            $data['country_code'] = $res;
        }else{
            oo::logs()->debug3(["type"=>3,"ip"=>$ip,"res"=>$res],'getIp');
        }
        if(empty($data)&&$limit<2){//再试一次
            $data = self::ip_info2($ip,2);
        }
        return $data;
    }

    /**
     * 远程调用
     * @param $url
     * @param mixed $sendData
     * @param string $type
     * @return bool|string
     * Created by: Owen
     * Created on: 2020/5/22 16:36
     */
    static function sendCurlPastThird($url,$sendData = [],$type="get"){
        if(IS_DEBUF){
            if(empty($sendData)){
                $sendData = ['sid'=>1,'lid'=>1,'mod'=>"Test",'act'=>"sendCurl",'url'=>$url,'service'=>1];
            }else{
                $sendData['sid'] = 1;
                $sendData['lid'] = 1;
                $sendData['service'] = 1;
            }
            //$url = "https://crazycoin.superant.vip/api/gateway.php";
            $url = "http://47.90.250.184/api/gateway.php";
            
            $type= "post";
        }
        return self::sendCurl($url,$sendData,$type);
    }

    /**
     * Notes:通用curl请求
     * User: wsc
     * Time: 2020/6/12 17:10
     * @param $url
     * @param array $sendData
     * @param string $type
     * @return bool|string
     */
    static function sendCurl($url,$sendData = [],$type="get"){
        //初始化
        $curl = curl_init();
        //设置
        curl_setopt($curl, CURLOPT_URL, $url);
        //设置头文件的信息作为数据流输出
        curl_setopt($curl, CURLOPT_HEADER, false);
        //设置获取的信息以文件流的形式返回，而不是直接输出。
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
        //设置连接超时时间
        curl_setopt($curl, CURLOPT_CONNECTTIMEOUT, 20);
        //设置1秒超时
        curl_setopt($curl, CURLOPT_TIMEOUT, 30);
        //https 设置
        if(strpos($url, 'https') !== false){
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, FALSE);
        }
        if($type=='post'){
            //设置post方式提交
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $sendData);
        }
        //执行命令
        $data = curl_exec($curl);
        if($data === FALSE)
        {
            echo "<br/>","cUrl Error:".curl_error($curl);
        }
        //关闭URL请求
        curl_close($curl);
        return $data;
    }

    /**
     * MAC 地址转换 SiteUid
     * @param $macAddr
     * @return int|string
     * Created by: Owen
     * Created on: 2020/5/22 16:38
     */
    static function macToSiteUid($macAddr) {
        $macAddr = trim($macAddr);
        if(strlen($macAddr) > 30){
            return 0;
        }
        $match = array();
        if (!preg_match("/^[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f][:-]"."[0-9a-f][0-9a-f]/i", $macAddr, $match)) {
            return 0;
        }
        return base_convert('0x'.strtr($macAddr, [':' => '']), 16, 10);
    }

    static function checkIosDeviceId($deviceId = '') {
        $regStr = '[a-zA-Z0-9]';
        if (!preg_match("/^".$regStr."{8}[-]".$regStr."{4}[-]".$regStr."{4}[-]".$regStr."{4}[-]".$regStr."{12}/i", $deviceId, $match)) {
            return false;
        }
        return true;
    }

    /**
     * 取整
     * @param $num
     * @param int $rounding
     * @return int|mixed
     * Created by: Owen
     * Created on: 2020/5/29 16:48
     */
    static function Rounding($num,$rounding = 1000){
        $num = max(0,intval($num));
        if($num < $rounding){
            return $num;
        }
        $new_num =  ($num / $rounding) ;
        return intval(floor($new_num)*$rounding);
    }

    /**
     * Notes:创建表
     * User: wsc
     * Time: 2020/6/12 17:17
     * @param $tbName "crazyGod_log.assetslog_20200612"
     * @return bool
     */
    static function createTable($tbName,$sql){
        $res = true;
        $dbInfo = explode('.',$tbName);
        include_once PATH_LIB . 'class.db.php';
        $cfg = oo::$config['db_'.strtolower($dbInfo[0])];
        if(IS_DEBUF&&$dbInfo[0]=='crazyGod_log'){//测试库大写
            $cfg[0][3] = $dbInfo[0];
        }
        $db = new DB($cfg);
        $db::$mysqli=[];
        $query = "SHOW TABLES LIKE '$dbInfo[1]'";
        $tbInfo = $db->getOne($query,1);
        if(empty($tbInfo)){
            $res =$db->query($sql);
        }else{
            $res = false;
        }
        return $res;
    }


    /**
     * 判断email
     * @param $email
     * @return bool
     * Created by: Owen
     * Created on: 2020/6/28 15:27
     */
    static function isEmail($email){
        if (filter_var($email, FILTER_VALIDATE_EMAIL)) {
            return true;
        } else {
            return false;
        }
    }

    //判断否为UTF-8编码
    static function is_utf8($str){
        $len = strlen($str);
        for($i = 0; $i < $len; $i++){ $c = ord($str[$i]); if($c > 128){
            if(($c > 247)){
                return false;
            }elseif($c > 239){
                $bytes = 4;
            }elseif($c > 223){
                $bytes = 3;
            }elseif ($c > 191){
                $bytes = 2;
            }else{
                return false;
            }
            if(($i + $bytes) > $len){
                return false;
            }
            while($bytes > 1){
                $i++;
                $b = ord($str[$i]);
                if($b < 128 || $b > 191){
                    return false;
                }
                $bytes--;
            }
        }
        }
        return true;
    }
    //判断是否base64加密
    static function is_base64($str){
        //这里多了个纯字母和纯数字的正则判断
        if(@preg_match('/^[0-9]*$/',$str) || @preg_match('/^[a-zA-Z]*$/',$str)){
            return false;
        }elseif(self::is_utf8(base64_decode($str)) && base64_decode($str) != ''){
            return true;
        }
        return false;
    }

    static function bet($bet){
        $bet = abs($bet);
        $bet = $bet>1000?1000:$bet;
        return $bet;
    }

    static function objectToArray($object){
        $array = [];
        foreach ($object as $key=>$row){
            $array[$key] = $row;
        }
        return $array;
    }

    /**
     * 创建随机字符串最长24位
     * @param int $num
     * @return string
     * Created by: Owen
     * Created on: 2020/8/26 11:23
     */
    static function getRandStrCode($num = 8){
        $code = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $rand = $code[rand(0, 25)] . strtoupper(dechex(date('m'))) . date('d') . substr(time(), -5) . substr(microtime(), 2, 5) . sprintf('%02d', rand(0, 99));
        $a = md5($rand);
        $s = '0123456789ABCDEFGHIJKLMNOPQRSTUV';
        $d = '';
        for ($f = 0;$f < $num;$f++){
            $g = ord($a[$f]);
            $d .= $s[($g ^ ord($a[$f + 8])) - $g & 0x1F];
        }
        return $d;
    }

    /**
     * 数字转货币格式
     * @param $num
     * @return string
     * Created by: Owen
     * Created on: 2020/9/12 15:16
     */
    static function CoinFormat($num){
        return number_format($num);
        $formatter = new NumberFormatter('en_US', NumberFormatter::CURRENCY);
        return ltrim($formatter->formatCurrency($num, 'RMB'),'RMB');
    }

    /**
     * 过滤空字符串或者null
     * @param $arr
     * @return array
     * Created by: Owen
     * Created on: 2020/10/29 19:36
     */
    static function ArrayFilter($arr){
        foreach ($arr as $key=>$row){
            if($row === '' || $row === null){
                unset($arr[$key]);
            }
        }
        return array_values($arr);
    }

    /**
     * 修改版本长度
     * @param $version
     * @param int $len
     * @return string
     * Created by: Owen
     * Created on: 2020/11/19 18:02
     */
    static function changeVersionLength($version,$len = 3){
        $version = explode('.',$version);
        $output  = [];
        for ($i=0;$i<$len;$i++){
            $output[] = $version[$i]??0;
        }
        return implode('.',$output);
    }

    /**
     * Notes:判断版本是否大于等于一组版本号内所有版本
     * User: wsc
     * Time: 2021/2/4 17:34
     * @param $dversion string 要比较的版本 '1.8.0'
     * @param $versions array 被比较的一组版本号['1.8.0','1.8.1']
     * @return bool
     */
    static function compareVersionArr($dversion,$versions){
        foreach ($versions as $version){
            if(!oo::compareVersion($dversion,$version)){
                return false;
            }
        }
        return true;
    }
    /**
     * 广告ID转MAC地址
     * @param $idStr
     * @return string
     * Created by: Owen
     * Created on: 2021/1/12 14:59
     */
    static function AdvertisementIdToSiteUid($idStr){
        $idStr = strtoupper($idStr);
        $len = strlen($idStr);
        $tmp = [];
        for ($i=0;$i<$len;$i++){
            $tmp[] = ord($idStr[$i]);
        }
        $tmp = implode('',$tmp);
        $out = [];
        $len = strlen($tmp);
        for ($i=0;$i<$len;$i++){
            if($len-$i-1 <= $i){
                break;
            }
            $out[] = ($tmp[$i] + $tmp[$len-1-$i]) % 10;
        }
        $out[] = $tmp[0];
        $out[] = $tmp[$len-1];
        $out = implode('',$out);
        if(strlen($out) >= 20){
            $out = mb_substr($out,0,19);
        }
        return $out;
    }

    /**
     * Notes:消维取键值
     * User: wsc
     * Time: 2021/3/9 18:05
     * @param $array
     * @param $columnkey
     * @param null $indexkey
     * @return array
     */
    static function array_column_ext($array, $columnkey, $indexkey = null) {
        $result = array();
        foreach ($array as $subarray => $value) {
            if (array_key_exists($columnkey,$value)) { $val = $array[$subarray][$columnkey]; }
            else if ($columnkey === null) { $val = $value; }
            else { continue; }

            if ($indexkey === null) { $result[] = $val; }
            elseif ($indexkey == -1 || array_key_exists($indexkey,$value)) {
                $result[($indexkey == -1)?$subarray:$array[$subarray][$indexkey]] = $val;
            }
        }
        return $result;
    }

    /**
     * 登录异常日记
     * @param $logMsg
     * @param string $file
     * @return mixed
     * Created by: Owen
     * Created on: 2021/4/10 11:14
     */
    static function errLog($logMsg, $file = 'mobileError') {
        $array = debug_backtrace();
        $path = [];
        foreach ($array as $row) {
            $path[] = $row['file'] . ':' . $row['line'] . '行,调用方法:' . $row['function'];
        }
        $logMsg['path'] = $path;
        oo::logs()->debug5($logMsg, $file.'.log',"loginError/".date('Ymd').'/');
        return $logMsg;
    }
    /**
     * Notes:给golang 发送nsq 指定格式消息
     * User: wsc
     * Time: 2021/8/18 20:23
     * @param $topic string "activityOnlineOff"
     * @param array $hearder
     * @param array $body ["aid"=>1,"actType"=>"rank","status"=>1]
     */
    static function SendNsqMsg($topic,$hearder,$body=[]){
        //目前只在测试条件下开启
//        if(!IS_DEBUF){
//            return true;
//        }
        if(IS_DEBUF){
//            $nsqdAddr = ["10.0.24.134:4150"];
            $nsqdAddr = oo::$config['nsqAddress'];
        }else{
//            $nsqdAddrs = ["172.22.107.123:4150","172.22.107.124:4150","172.22.107.125:4150"];
            $nsqdAddrs = oo::$config['nsqAddress'];
            $nsqdAddr=[$nsqdAddrs[0]];
        }
        $bodyArr = $body;
        $body =array_values( unpack("C*", json_encode($body)));
        if(empty($hearder)){
            $hearder =["test"=>"test"];
        }
        $data = ["header"=>$hearder,"body"=>$body];
        $nsq = new Nsq();
        $isTrue = $nsq->connectNsqd($nsqdAddr);
        if(!$isTrue&&!IS_DEBUF){
            $isTrue = $nsq->connectNsqd([$nsqdAddrs[1]]);
            if(!$isTrue){
                $isTrue = $nsq->connectNsqd([$nsqdAddrs[2]]);
            }
        }

//        echo "Is connect:".$isTrue;
        if($isTrue){
            $res = $nsq->publish($topic,json_encode($data));
            if(!$res){
                oo::logs()->commlog(["msg"=>"publish is lost","topic"=>$topic,"info"=>$bodyArr],"phpToGo_err.log");
            }
//            if (in_array($topic,[ocmd::TopicActOnlineOff,ocmd::TopicActTimeLimit])||$bodyArr['cmd']==ocmd::$send['ActivityChangeStatus_New']){
                oo::logs()->commlog(["res"=>$res,"topic"=>$topic,"info"=>$bodyArr],"phpToGo.log");
//            }
            $nsq->closeNsqdConnection();
        }else{
            oo::logs()->commlog(["msg"=>"lose connect...","topic"=>$topic,"info"=>$bodyArr],"phpToGo_err.log");
        }
        return $res;
    }

    public static function curlPost($url, $header = [], $data = [], $method = 'post', $tryTimes = 0){
        $curl = curl_init();
        if(!empty($header)){
            curl_setopt($curl, CURLOPT_HTTPHEADER, $header);
            curl_setopt($curl, CURLOPT_HEADER, 0);//返回response头部信息
        }
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($curl, CURLOPT_TIMEOUT, 120);


        if(strtolower($method)=='post'){
            curl_setopt($curl, CURLOPT_POST, 1);
            curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
        }

        curl_setopt($curl, CURLOPT_RETURNTRANSFER, TRUE);
        $output = curl_exec($curl);
        $cherror = curl_error($curl);
        curl_close($curl);
        if(!empty($cherror)){
            oo::logs()->debug3(   'curlerror:'.$cherror ,'curlPostError');
            if($tryTimes < 5){
                $tryTimes++;
                return  self::curlPost($url, $header, $data, $method, $tryTimes);
            }
        }
        return $output;
    }
    public static function createcsv($csv_body,$csv_header,$type=1,$filename='res01'){
        // 头部标题
        //    $csv_header = array('UID','创建角色时间','名字','当前等级','充值金额（美元）');

        /**
         * 开始生成
         * 1. 首先将数组拆分成以逗号（注意需要英文）分割的字符串
         * 2. 然后加上每行的换行符号，这里建议直接使用PHP的预定义
         * 常量PHP_EOL
         * 3. 最后写入文件
         */
        // 打开文件资源，不存在则创建
        $des_file = PATH_DAT.'/upload_csv/'.$filename.'.csv';
        $fp = fopen(    $des_file,'a');
        // 处理头部标题
        $header = !empty($csv_header)?implode(',', $csv_header) . PHP_EOL:'';
        // 处理内容
        $content = '';
//    var_dump($csv_body);
        foreach ($csv_body as $k => $v) {
            if($type==1){
                $content .= implode(',', $v) . PHP_EOL;
            }else if($type==2){
                foreach ($v as $key => $value) {
                    $content .= implode(',', $v) . PHP_EOL;
                }
            }else if($type=3){
                $content .= $v.PHP_EOL;
            }

        }
        // 拼接
        $csv = $header.$content;
        // 写入并关闭资源
        fwrite($fp, $csv);
        fclose($fp);
    }
}
