<?php 
	/** 公用函数 */

    //导出数据
    //导出数据
    function exportExcel($expTitle, $expCellName, $expTableData)
    {
        $xlsTitle = iconv('utf-8', 'gb2312', $expTitle);//文件名称
        $fileName = $expTitle.date('_YmdHis');//or $xlsTitle 文件名称可根据自己情况设定
        $cellNum = count($expCellName);
        $dataNum = count($expTableData);

        // vendor("PHPExcel.PHPExcel");

        $objPHPExcel = new PHPExcel(); 
        include_once(__DIR__."/../../vendor/PHPExcel/PHPExcel/IOFactory.php");
        set_time_limit(0);//不对php(主要是写数据)执行时间做限制
        ini_set("memory_limit", "1024M");//设置内存(防爆内存)
        $cacheMethod = \PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized;//设置缓存策略(减少内存占用)
        //判断缓存策略是否可用
        if (!\PHPExcel_Settings::setCacheStorageMethod($cacheMethod)) {
            die($cacheMethod . " 缓存方法不可用" . EOL);
        }

        $cellName = array('A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','AA','AB','AC','AD','AE','AF','AG','AH','AI','AJ','AK','AL','AM','AN','AO','AP','AQ','AR','AS','AT','AU','AV','AW','AX','AY','AZ');
        //显示导出名称和导出时间
        // $objPHPExcel->getActiveSheet(0)->mergeCells('A1:'.$cellName[$cellNum-1].'1');//合并单元格
        // $objPHPExcel->setActiveSheetIndex(0)->setCellValue('A1', $expTitle.'  导出时间:'.date('Y-m-d H:i:s'));
        for($i=0;$i<$cellNum;$i++){
            $objPHPExcel->setActiveSheetIndex(0)->setCellValue($cellName[$i].'1', $expCellName[$i][1]);
        }
        // Miscellaneous glyphs, UTF-8
        for($i=0;$i<$dataNum;$i++){
            for($j=0;$j<$cellNum;$j++){
                $objPHPExcel->getActiveSheet(0)->setCellValue($cellName[$j].($i+2), $expTableData[$i][$expCellName[$j][0]]);
            }
        }

        header('pragma:public');
        header('Content-type:application/vnd.ms-excel;charset=utf-8;name="'.$xlsTitle.'.csv"');
        header("Content-Disposition:attachment;filename=$fileName.csv");//attachment新窗口打印inline本窗口打印
        //输出bom
        print(chr(0xEF).chr(0xBB).chr(0xBF));
        $objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'CSV');
        $objWriter->save('php://output');
        exit;
    }

    // curl 
	function curlApi( $url , $params = array(), $method = 'GET' , $multi = false, $extheaders = array())
	{
        if(!function_exists('curl_init')) exit('Need to open the curl extension');
        $method = strtoupper($method);
        $ci = curl_init();
        curl_setopt($ci, CURLOPT_CONNECTTIMEOUT, 10);
        curl_setopt($ci, CURLOPT_TIMEOUT, 10);
        curl_setopt($ci, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ci, CURLOPT_SSL_VERIFYPEER, false);
        curl_setopt($ci, CURLOPT_SSL_VERIFYHOST, false);
        curl_setopt($ci, CURLOPT_HEADER, false);
        curl_setopt($ci, CURLOPT_REFERER, $_SERVER['HTTP_HOST']);
        $headers = (array)$extheaders;
        switch ($method)
        {
            case 'POST':
                curl_setopt($ci, CURLOPT_POST, TRUE);
                if (!empty($params))
                {
                    if($multi)
                    {
                        foreach($multi as $key => $file)
                        {
                            $params[$key] = '@' . $file;
                        }
                        curl_setopt($ci, CURLOPT_POSTFIELDS, $params);
                        $headers[] = 'Expect: ';
                    }
                    else
                    {
                        curl_setopt($ci, CURLOPT_POSTFIELDS, http_build_query($params));
                    }
                }
                break;
            case 'DELETE':
            case 'GET':
                $method == 'DELETE' && curl_setopt($ci, CURLOPT_CUSTOMREQUEST, 'DELETE');
                if (!empty($params))
                {
                    $url = $url . (strpos($url, '?') ? '&' : '?')
                        . (is_array($params) ? http_build_query($params) : $params);
                }
                break;
        }
        curl_setopt($ci, CURLINFO_HEADER_OUT, TRUE );
        curl_setopt($ci, CURLOPT_URL, $url);
        if($headers)
        {
            curl_setopt($ci, CURLOPT_HTTPHEADER, $headers );
        }

        $response = curl_exec($ci);
        curl_close ($ci);
        return $response;
    }

    /**
     * webpower CURL 请求
     * @param $url
     * @param $content
     * @param string $method
     * @return mixed
     */
    function webpower_curl($url, $content, $method= 'post'){
        //username and password
        $username = "xb@ichunt.com";   //短信平台的账号
        $password = "Webp0wer";        //短信平台的密码

        $data_string = json_encode($content);
        $header = array(
            "Content-Type: application/json",
            "X-HTTP-Method-Override: $method",
            "Authorization: Basic " . base64_encode($username . ":" . $password)
        );

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_FAILONERROR, 0);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, $data_string);

        curl_setopt($ch,CURLOPT_HTTPHEADER, $header);
        $response = curl_exec($ch);
        return $response ? $response : curl_error($ch);
    }

    /**
     * 接口服务时加密方式
     * @param  [type] $data      [description]
     * @param  [type] $timestamp [description]
     * @param  [type] $key       [description]
     * @return [type]            [description]
     */
    function service_token($data, $timestamp, $key = null)
    {
        $key = is_null($key) ? Config('website.SERVICE_KEY') : $key;
        $token = md5($data.$timestamp.$key);
        return $token;
    }

    /**
     * 获取客户端IP地址
     * @param integer $type 返回类型 0 返回IP地址 1 返回IPV4地址数字
     * @param boolean $adv 是否进行高级模式获取(有可能被伪装)
     * @return mixed
     */
    function get_client_ip($type = 0, $adv = false)
    {
        $type      = $type ? 1 : 0;
        static $ip = null;
        if (null !== $ip) {
            return $ip[$type];
        }

        if ($adv) {
            if (isset($_SERVER['HTTP_X_FORWARDED_FOR'])) {
                $arr = explode(',', $_SERVER['HTTP_X_FORWARDED_FOR']);
                $pos = array_search('unknown', $arr);
                if (false !== $pos) {
                    unset($arr[$pos]);
                }

                $ip = trim($arr[0]);
            } elseif (isset($_SERVER['HTTP_CLIENT_IP'])) {
                $ip = $_SERVER['HTTP_CLIENT_IP'];
            } elseif (isset($_SERVER['REMOTE_ADDR'])) {
                $ip = $_SERVER['REMOTE_ADDR'];
            }
        } elseif (isset($_SERVER['REMOTE_ADDR'])) {
            $ip = $_SERVER['REMOTE_ADDR'];
        }
        // IP地址合法验证
        $long = sprintf("%u", ip2long($ip));
        $ip   = $long ? array($ip, $long) : array('0.0.0.0', 0);
        return $ip[$type];
    }

    // 记录错误日志
    function errorLog($err_code, $err_msg)
    {
        $near_trace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS, 2);
        $backtrace = array_pop($near_trace);

        $file = !empty($near_trace[0]['file']) ? $near_trace[0]['file'] : '';
        $line = !empty($near_trace[0]['line']) ? $near_trace[0]['line'] : 0;
        $method = !empty($backtrace['function']) ? $backtrace['function'] : '';

        \LogReport::write(\LogReport::anlyError($err_msg, $file, $line, $err_code, $method));
    }

    function Crumbs($menus, $uri)
    {
        $actives = [];
        CheckActive($menus, $actives, $uri);
        $ret = '';
        foreach ($actives as $k => $v) {
            if ($k == count($actives) - 1) {
                $ret .= '<li class="active"><a>' . $menus[$actives[0]]->childs[$actives[1]]->title . '</a></li>';
            } else {
                $ret .= '<li><a href="#">' . $menus[$actives[0]]->title . '</a></li>';
            }
        }

        return $ret;
    }

    function CheckActive($menus, &$arr, $url)
    {
        for ($i = 0; $i < count($menus); $i++) {
            $menu = $menus[$i];
            array_push($arr, $i);

            if (isset($menu->href) && ($menu->href == $url || ($menu->href == '/' && $url == '//')))
                return true;
            if (isset($menu->childs) && count($menu->childs) > 0) {
                $ret = CheckActive($menu->childs, $arr, $url);
                if ($ret)
                    return $ret;
            }
            array_pop($arr);
        }

        return false;
    }

    function createMenuReal($menus, $active, $level)
    {
        $subclass = ($level == 0) ? 'nav-second-level' : 'nav-third-level';

        $ret = '';
        for ($ii = 0; $ii < ($level == 0 ? 1 : 2); $ii++) {
            for ($i = 0; $i < count($menus); $i++) {
                $menu = $menus[$i];
                $act = (count($active) > $level && $active[$level] == $i) ? true : false;
                $actclass = $act ? ' class="active"' : '';
                $actmenu  = $act ? ' in': '';

                if (isset($menu->childs) && count($menu->childs) > 0) {
                    if ($ii != 0 && $level > 0)
                        continue;
                    $ret .= '<li'. $actclass .'><a><i class="'
                        . $menu->class . '"></i><span class="nav-label">'
                        . $menu->title . '</span><span class="fa arrow"></span></a>'
                        . '<ul class="nav ' . $subclass . ' collapse' . $actmenu . '">'
                        . createMenuReal($menu->childs, $act ? $active : [], $level + 1)
                        . '</ul></li>';
                } else {
                    if ($ii != 1 && $level > 0)
                        continue;
                    $ret .= '<li' . $actclass . '><a href="'. $menu->href . '"><i class="' .
                        $menu->class . '"></i><span class="nav-label">' . $menu->title . '</span></a></li>';
                }
            }
        }

        return $ret;
    }

    function createMenu($menus, $url)
    {
        $actives = [];
        $ret = CheckActive($menus, $actives, $url);
        if (!$ret)
            $actives = [];
        return createMenuReal($menus, $actives, 0);
    }
    //过滤数据
    function TrimX($data='',$empty=true,$arr=false){
        if(is_array($data)){
            foreach ($data as $k=>$v){
                if(!empty($v) && $v!=0 && !is_array($v)){
                    $data[$k]=trim($v);
                }
                if($empty==true){
                    if((empty($v) && $v!=0) || $v=='undefined' || $v==null){
                        unset($data[$k]);
                    }
                }
                if(is_array($arr) && count($arr)>0 && count($data)>0){
                    if(!in_array($k,$arr)){
                        unset($data[$k]);
                    }
                }
            }
        }else{
            $data=trim($data);
        }
        return $data;
    }
/**
 * 导出CSV文件
 * @param array $data        数据
 * @param array $header_data 首行数据
 * @param string $file_name  文件名称
 * @return string
 */
function export_csv($data = [], $header_data = [], $file_name = '')
{
    set_time_limit(0);
    header('Content-Type: application/vnd.ms-excel');
    header('Content-Disposition: attachment;filename='.$file_name);
    header('Cache-Control: max-age=0');
    $fp = fopen('php://output', 'a');
    if (!empty($header_data)) {
        foreach ($header_data as $key => $value) {
            $header_data[$key] = iconv('utf-8', 'gbk', $value);
        }
        fputcsv($fp, $header_data);
    }
    $num = 0;
    $limit = 100000; //每隔$limit行,刷新一下输出buffer,不要太大,也不要太小
    $count = count($data); //逐行取出数据,不浪费内存
    if ($count > 0) {
        for ($i = 0; $i < $count; $i++) {
            $num++;
            //刷新一下输出buffer,防止由于数据过多造成问题
            if ($limit == $num) {
                ob_flush();
                flush();
                $num = 0;
            }
            $row = $data[$i];
            foreach ($row as $key => $value) {
                $row[$key] = iconv('utf-8', 'gbk', $value);
            }
            fputcsv($fp, $row);
        }
    }
    fclose($fp);exit;
}
/*
 *所有变量转字符串
 */
function  changeToStr($str){
    return sprintf("'%s'", $str);
}
/*
 * 取二维数组某一列的值生成以逗号分隔的字符串,如:$data = ['0'=>['uid'=>'1313','name'=>121],'1'=>['uid'=>'1414','name'=>121]]
   转换后变为:arrayTostr($data,'uid')  =》1313,1414
 * @param array $data  要取值的数组
 * @param string $s 下标:如 uid
 * @param string $type 类型,1为控制返回null,2 返回数字
 * @return str
 */
function arrayToCommaStr($data,$col,$type=''){
    switch ($type){
        case 1:  //如果计算后的值是空,返回空
            return array_filter(array_column($data,$col));
            break;
        case 2:
            $arr = array_unique(array_column($data,$col));
            return $res = implode(',',$arr);
            break;
        case 3:
            $arr = array_filter(array_column($data,$col));
            $res = implode(',',array_map('changeToStr',$arr)); //回调本类中的changeToStr 函数
            return $res == "" ? "NULL" : $res;
            break;
        default:
            $arr = array_filter(array_column($data,$col));
            $res = implode(',',array_map('changeToStr',$arr)); //回调本类中的changeToStr 函数
            return  $res;
            break;
    }
}
/**
 * 对象转换数组
 *
 * @param $e StdClass对象实例
 * @return array|void
 */
 function objectToArray($e)
{
    $e = (array)$e;
    foreach ($e as $k => $v) {
        if (gettype($v) == 'resource') return;
        if (gettype($v) == 'object' || gettype($v) == 'array')
            $e[$k] = (array)objectToArray($v);
    }
    return $e;
}
// 计算中文字符串长度
function utf8_strlen($string = null) {
    // 将字符串分解为单元
    preg_match_all("/./us", $string, $match);
    // 返回单元个数
    return count($match[0]);
}