博客

  • php 向二维数组中追加元素

    处理之前的数据:

     

    处理后:

    //$consult 为往里插之前的数组
            //把$arr的元素追加到$consult的最前面
            $arr = [];
            $arr[0]['workplaceId'] = '0';
            $arr[0]['workplaceName'] = '信息部';
            $arr[0]['List'] = [['typeId' => 3, 'typeName' => '全部']];
            array_walk($arr,function($item) use (&$consult) {
                array_unshift($consult, $item);
            });
  • mysql高效率随机取一条或多条数据

    本文详细解说了MySQL Order By Rand()效率优化的方案,并给出了优化的思路过程,是篇不可多得的MySQL Order By Rand()效率美文。  

          最近由于需要大概研究了一下MYSQL的随机抽取实现方法。举个例子,要从tablename表中随机提取一条记录,大家一般的写法就是:SELECT * FROM tablename ORDER BY RAND() LIMIT 1。  
     
          但是,后来我查了一下MYSQL的官方手册,里面针对RAND()的提示大概意思就是,在ORDER BY从句里面不能使用RAND()函数,因为这样会导致数据列被多次扫描。但是在MYSQL 3.23版本中,仍然可以通过ORDER BY RAND()来实现随机。  
     
    但是真正测试一下才发现这样效率非常低。一个15万余条的库,查询5条数据,居然要8秒以上。查看官方手册,也说rand()放在ORDER BY 子句中会被执行多次,自然效率及很低。  
     
    You cannot use a column with RAND() values in an ORDER BY clause, because ORDER BY would evaluate the column multiple times.  
    搜索Google,网上基本上都是查询max(id) * rand()来随机获取数据。  
    SELECT *   
    FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * (SELECT MAX(id) FROM `table`)) AS id) AS t2   
    WHERE t1.id >= t2.id   
    ORDER BY t1.id ASC LIMIT 5;  
    但是这样会产生连续的5条记录。解决办法只能是每次查询一条,查询5次。即便如此也值得,因为15万条的表,查询只需要0.01秒不到。  
     
    下面的语句采用的是JOIN,mysql的论坛上有人使用  
    SELECT *   
    FROM `table`   
    WHERE id >= (SELECT FLOOR( MAX(id) * RAND()) FROM `table` )   
    ORDER BY id LIMIT 1;  
    我测试了一下,需要0.5秒,速度也不错,但是跟上面的语句还是有很大差距。总觉有什么地方不正常。  
     
    于是我把语句改写了一下。  
    SELECT * FROM `table`   
    WHERE id >= (SELECT floor(RAND() * (SELECT MAX(id) FROM `table`)))    
    ORDER BY id LIMIT 1;  
    这下,效率又提高了,查询时间只有0.01秒  
     
    最后,再把语句完善一下,加上MIN(id)的判断。我在最开始测试的时候,就是因为没有加上MIN(id)的判断,结果有一半的时间总是查询到表中的前面几行。  
    完整查询语句是:  
    SELECT * FROM `table`   
    WHERE id >= (SELECT floor( RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`)) + (SELECT MIN(id) FROM `table`)))    
    ORDER BY id LIMIT 1;  
    SELECT *   
    FROM `table` AS t1 JOIN (SELECT ROUND(RAND() * ((SELECT MAX(id) FROM `table`)-(SELECT MIN(id) FROM `table`))+(SELECT MIN(id) FROM `table`)) AS id) AS t2   
    WHERE t1.id >= t2.id   
    ORDER BY t1.id LIMIT 1;  
    最后在php中对这两个语句进行分别查询10次,  
    前者花费时间 0.147433 秒  
    后者花费时间 0.015130 秒  
    看来采用JOIN的语法比直接在WHERE中使用函数效率还要高很多。  
     
    参考文献:  
    MySQL Order By索引优化:http://www.phpq.net/mysql/mysql-order-by.html  
    MySQL Order By语法:http://www.phpq.net/mysql/mysql-order-by-syntax.html  
    MySQL Order By Rand()效率:http://www.phpq.net/mysql/mysql-order-by-rand.html  
    MySQL Order By用法:http://www.phpq.net/mysql/mysql-order-by-use.html

  • 实用的PHP函数集合20201017

    /* 对象转数组 */
        function object_to_array($obj) {
            $obj = (array)$obj;
            foreach ($obj as $k => $v) {
                if (gettype($v) == 'resource') {
                    return;
                }
                if (gettype($v) == 'object' || gettype($v) == 'array') {
                    $obj[$k] = (array)object_to_array($v);
                }
            }
         
            return $obj;
        }

    //数组转对象
    function array_object($array) {
        if (gettype($array) != 'array') {
            return;
        }
        foreach ($array as $k => $v) {
            if (gettype($v) == 'array' || getType($v) == 'object') {
                $array[$k] = (object)$this->array_object($v);
            }
        }
    
        return (object)$array;
    }

    /* 文字替换*/

    function m_s($a){
            $url=$_SERVER[‘HTTP_HOST’];
            if($url=='zbsc.yunbaozb.com'){
                $l=strlen($a);
                $sl=$l-6;
                $s='';
                for($i=0;$i<$sl;$i++){
                    $s.='*';
                }
                $rs=substr_replace($a,$s,3,$sl);
                return $rs;
            }
            return $a;
        }

    /**
     * 格式化输出
     */
    function dump($var, $echo = true, $label = null, $strict = true)
    {
        $label = ($label === null) ? '' : rtrim($label) . ' ';
        if (!$strict) {
            if (ini_get('html_errors')) {
                $output = print_r($var, true);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            } else {
                $output = $label . print_r($var, true);
            }
        } else {
            ob_start();
            var_dump($var);
            $output = ob_get_clean();
            if (!extension_loaded('xdebug')) {
                $output = preg_replace('/\]\=\>\n(\s+)/m', '] => ', $output);
                $output = '<pre>' . $label . htmlspecialchars($output, ENT_QUOTES) . '</pre>';
            }
        }
        if ($echo) {
            echo($output);
            return null;
        } else
            return $output;
    }

    /**
     * 版本号比较,位数一定要相等,例2.13.5和2.13.4或1.24.5.2和2.2.2.2
     * @param $base_version
     * 基准版本号
     * @param $version
     * 比对版本号
     * @return bool -1小,0相等,1大
     */
    function versionBool($base_version, $version)
    {
        $base_version = explode('.', $base_version);
        $version = explode('.', $version);
        $count = count($base_version);
        for ($i = 0; $i < $count; $i++) {
            if ($base_version[$i] < $version[$i]) {
                return 1;
            } elseif ($base_version[$i] == $version[$i] && $i >= $count – 1) {//相等的情况,需要三个版本位都相等
                return 0;
            } elseif ($base_version[$i] > $version[$i]) {
                return -1;
            }
        }
        return true;
    }


    /* 时长格式化 */
    function secondsFormat($time)
    {

        $now = time();
        $cha = $now – $time;

        if ($cha < 60) {
            return '刚刚';
        }

        if ($cha >= 4 * 24 * 60 * 60) { //超过4天
            $now_year = date('Y', $now);
            $time_year = date('Y', $time);

            if ($now_year == $time_year) {
                return date("m月d日", $time);
            } else {
                return date("Y年m月d日", $time);
            }

        } else {

            $iz = floor($cha / 60);
            $hz = floor($iz / 60);
            $dz = floor($hz / 24);

            if ($dz > 3) {
                return '3天前';
            } else if ($dz > 2) {
                return '2天前';
            } else if ($dz > 1) {
                return '1天前';
            }

            if ($hz > 1) {
                return $hz . '小时前';
            }

            return $iz . '分钟前';
        }

    }

    ///////////////////////////////////////快递鸟物流信息查询start/////////////////////////////////////////////

    //获取物流状态【即时查询版】
    function getExpressStateInfo($express_code, $express_number, $express_name, $username)
    {

        $express_info = [];

        $express_info_kdn = getExpressInfoByKDN($express_code, $express_number);
        $express_state = $express_info_kdn[‘State’]; //物流状态 0-暂无轨迹信息 1-已揽收 2-在途中  3-已签收4-问题件

        if (!$express_state) {
            $express_info[‘state_name’] = '包裹正在等待揽收';
            $express_info[‘desc’] = $express_name . ' ' . $express_number;
        } elseif ($express_state == 1) {
            $express_info[‘state_name’] = '包裹已揽收';
            $express_info[‘desc’] = $express_name . ' ' . $express_number;
        } elseif ($express_state == 2) {
            $express_info[‘state_name’] = '包裹运输中';
            $express_info[‘desc’] = $express_name . ' ' . $express_number;
        } elseif ($express_state == 3) {
            $express_info[‘state_name’] = '包裹已签收';
            $express_info[‘desc’] = '签收人:' . $username;
        }

        return $express_info;
    }

        //快递鸟获取物流信息
        function getExpressInfoByKDN($express_code,$express_number){

            $configpri=getConfigPri();
            $express_type=isset($configpri[‘express_type’])?$configpri[‘express_type’]:'';
            $EBusinessID=isset($configpri[‘express_id_dev’])?$configpri[‘express_id_dev’]:'';
            $AppKey=isset($configpri[‘express_appkey_dev’])?$configpri[‘express_appkey_dev’]:'';

            //$ReqURL='http://sandboxapi.kdniao.com:8080/kdniaosandbox/gateway/exterfaceInvoke.json'; //免费版即时查询【快递鸟测试账号专属查询地址】
            $ReqURL='http://api.kdniao.com/Ebusiness/EbusinessOrderHandle.aspx'; //免费版即时查询【已注册商户ID真实即时查询地址】

            if($express_type){ //正式付费物流跟踪版
                $EBusinessID=isset($configpri[‘express_id’])?$configpri[‘express_id’]:'';
                $AppKey=isset($configpri[‘express_appkey’])?$configpri[‘express_appkey’]:'';
                $ReqURL='http://api.kdniao.com/api/dist'; //物流跟踪版查询【已注册商户ID真实即时查询地址】
            }


            
            
            
            $requestData=array(
                'ShipperCode'=>$express_code,
                'LogisticCode'=>$express_number
            );

            $requestData= json_encode($requestData);
            
            $datas = array(
                'EBusinessID' => $EBusinessID,
                'RequestType' => '1002',
                'RequestData' => urlencode($requestData) ,
                'DataType' => '2',
            );

            //物流跟踪版消息报文
            if($express_type){
                $datas[‘RequestType’]='1008';
            }

            $datas[‘DataSign’] = encrypt_kdn($requestData, $AppKey);

            $result=sendPost_KDN($ReqURL, $datas);

            return json_decode($result,true);

        }

        /**
         * 快递鸟电商Sign签名生成
         * @param data 内容   
         * @param appkey Appkey
         * @return DataSign签名
         */
        function encrypt_kdn($data, $appkey) {
            return urlencode(base64_encode(md5($data.$appkey)));
        }

        /**
         *  post提交数据 
         * @param  string $url 请求Url
         * @param  array $datas 提交的数据 
         * @return url响应返回的html
         */
        function sendPost_KDN($url, $datas) {
            $temps = array();   
            foreach ($datas as $key => $value) {
                $temps[] = sprintf('%s=%s', $key, $value);      
            }   
            $post_data = implode('&', $temps);
            $url_info = parse_url($url);
            if(empty($url_info[‘port’]))
            {
                $url_info[‘port’]=80;   
            }
            $httpheader = "POST " . $url_info[‘path’] . " HTTP/1.0\r\n";
            $httpheader.= "Host:" . $url_info[‘host’] . "\r\n";
            $httpheader.= "Content-Type:application/x-www-form-urlencoded\r\n";
            $httpheader.= "Content-Length:" . strlen($post_data) . "\r\n";
            $httpheader.= "Connection:close\r\n\r\n";
            $httpheader.= $post_data;
            $fd = fsockopen($url_info[‘host’], $url_info[‘port’]);
            fwrite($fd, $httpheader);
            $gets = "";
            $headerFlag = true;
            while (!feof($fd)) {
                if (($header = @fgets($fd)) && ($header == "\r\n" || $header == "\n")) {
                    break;
                }
            }
            while (!feof($fd)) {
                $gets.= fread($fd, 128);
            }
            fclose($fd);  
            
            return $gets;
        }

        function is_true($val, $return_null=false){
            $boolval = ( is_string($val) ? filter_var($val, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE) : (bool) $val );
            return ( $boolval===null && !$return_null ? false : $boolval );
        }

        ///////////////////////////////////////快递鸟物流信息查询end/////////////////////////////////////////////

    /**
     * 判断是否为合法的身份证号码
     * @param $mobile
     * @return int
     */
    function isCreditNo($vStr)
    {

        return true;

        $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;
    }


    /* 时长格式化 */
    function getBanSeconds($cha, $type = 0)
    {
        $iz = floor($cha / 60);
        $hz = floor($iz / 60);
        $dz = floor($hz / 24);
        /* 秒 */
        $s = $cha % 60;
        /* 分 */
        $i = floor($iz % 60);
        /* 时 */
        $h = floor($hz / 24);
        /* 天 */

        if ($type == 1) {
            if ($s < 10) {
                $s = '0' . $s;
            }
            if ($i < 10) {
                $i = '0' . $i;
            }

            if ($h < 10) {
                $h = '0' . $h;
            }

            if ($hz < 10) {
                $hz = '0' . $hz;
            }
            return $hz . ':' . $i . ':' . $s;
        }


        if ($cha < 60) {
            return $cha . '秒';
        } else if ($iz < 60) {
            return $iz . '分钟' . $s . '秒';
        } else if ($hz < 24) {
            return $hz . '小时' . $i . '分钟';
        } else if ($dz < 30) {
            return $dz . '天' . $h . '小时';
        }
    }


    /* 生成二维码 */

    function scerweima($url = '')
    {

        $key = md5($url);

        //生成二维码图片
        $filename2 = '/upload/qr/' . $key . '.png';
        $filename = API_ROOT . '/../public/upload/qr/' . $key . '.png';

        if (!file_exists($filename)) {
            require_once API_ROOT . '/../sdk/phpqrcode/phpqrcode.php';

            $value = $url;                    //二维码内容

            $errorCorrectionLevel = 'H';    //容错级别
            $matrixPointSize = 6.2068965517241379310344827586207;            //生成图片大小

            //生成二维码图片
            \QRcode::png($value, $filename, $errorCorrectionLevel, $matrixPointSize, 2);
        }

        return $filename2;
    }

    /*距离格式化2*/
    function distanceFormatGeo($distance)
    {
        if(empty($distance))  return -1;
        $distance = floatval($distance);
        if ($distance < 1) {
            $a = floor($distance * 1000);
            $a = $a == 0 ? 1 : $a;
            return  $a . '米';
        } elseif ($distance < 100) {
            $b = number_format($distance, 1);
            if(($b*10) % 10 != 0){
                return $b . 'km';  //保留一位小数,会四舍五入
            }
            return floor($b) . 'km';
        }
        return floor($distance) . 'km';  //保留一位小数,会四舍五入
    }

    /* 校验签名 */
    function checkSign($data, $sign)
    {
        //废弃,走框架入口校验
        return 1;
          $key = DI()->config->get('app.sign_key');
          $str = '';
          ksort($data);
          foreach ($data as $k => $v) {
              $str .= $k . '=' . $v . '&';
          }

          $str .= $key;
          $newsign = md5($str);
          /*var_dump($newsign);
              die;*/
          if ($sign == $newsign) {
              return 1;
          }
          return 0;
    }

    /* 计算年龄 */
    function datediffage($before, $after)
    {
        if ($before > $after) {
            $b = getdate($after);
            $a = getdate($before);
        } else {
            $b = getdate($before);
            $a = getdate($after);
        }
        $n = array(1 => 31, 2 => 28, 3 => 31, 4 => 30, 5 => 31, 6 => 30, 7 => 31, 8 => 31, 9 => 30, 10 => 31, 11 => 30, 12 => 31);
        $y = $m = $d = 0;
        if ($a[‘mday’] >= $b[‘mday’]) { //天相减为正
            if ($a[‘mon’] >= $b[‘mon’]) {//月相减为正
                $y = $a[‘year’] – $b[‘year’];
                $m = $a[‘mon’] – $b[‘mon’];
            } else { //月相减为负,借年
                $y = $a[‘year’] – $b[‘year’] – 1;
                $m = $a[‘mon’] – $b[‘mon’] + 12;
            }
            $d = $a[‘mday’] – $b[‘mday’];
        } else {  //天相减为负,借月
            if ($a[‘mon’] == 1) { //1月,借年
                $y = $a[‘year’] – $b[‘year’] – 1;
                $m = $a[‘mon’] – $b[‘mon’] + 12;
                $d = $a[‘mday’] – $b[‘mday’] + $n[12];
            } else {
                if ($a[‘mon’] == 3) { //3月,判断闰年取得2月天数
                    $d = $a[‘mday’] – $b[‘mday’] + ($a[‘year’] % 4 == 0 ? 29 : 28);
                } else {
                    $d = $a[‘mday’] – $b[‘mday’] + $n[$a[‘mon’] – 1];
                }
                if ($a[‘mon’] >= $b[‘mon’] + 1) { //借月后,月相减为正
                    $y = $a[‘year’] – $b[‘year’];
                    $m = $a[‘mon’] – $b[‘mon’] – 1;
                } else { //借月后,月相减为负,借年
                    $y = $a[‘year’] – $b[‘year’] – 1;
                    $m = $a[‘mon’] – $b[‘mon’] + 12 – 1;
                }
            }
        }
        return (string)$y;
    }

    /* 时长格式化 */
    function getSeconds($cha, $type = 0)
    {

        if ($cha < 0) {
            return '0秒';
        }
        $iz = floor($cha / 60);
        $hz = floor($iz / 60);
        $dz = floor($hz / 24);
        /* 秒 */
        $s = $cha % 60;
        /* 分 */
        $i = floor($iz % 60);
        /* 时 */
        $h = floor($hz / 24);
        /* 天 */

        if ($type == 1) {
            if ($s < 10) {
                $s = '0' . $s;
            }
            if ($i < 10) {
                $i = '0' . $i;
            }

            if ($h < 10) {
                $h = '0' . $h;
            }

            if ($hz < 10) {
                $hz = '0' . $hz;
            }
            return $hz . ':' . $i . ':' . $s;
        }


        if ($cha < 60) {
            return $cha . '秒';
        } else if ($iz < 60) {
            return $iz . '分钟' . $s . '秒';
        } else if ($hz < 24) {
            return $hz . '小时' . $i . '分钟' . $s . '秒';
        } else {
            return $dz . '天' . $h . '小时' . $i . '分钟' . $s . '秒';
        }
    }

    /* 数字格式化 */
    function NumberFormat($num)
    {
        if ($num < 10000) {

        } else if ($num < 1000000) {
            $num = round($num / 10000, 2) . '万';
        } else if ($num < 100000000) {
            $num = round($num / 10000, 1) . '万';
        } else if ($num < 10000000000) {
            $num = round($num / 100000000, 2) . '亿';
        } else {
            $num = round($num / 100000000, 1) . '亿';
        }
        return $num;
    }

    /* 生成邀请码 */
        function createCode($len=6,$format='ALL'){
            $is_abc = $is_numer = 0;
            $password = $tmp =''; 
            switch($format){
                case 'ALL':
                    $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
                    break;
                case 'ALL2':
                    $chars='ABCDEFGHJKLMNPQRSTUVWXYZ0123456789';
                    break;
                case 'CHAR':
                    $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz';
                    break;
                case 'NUMBER':
                    $chars='0123456789';
                    break;
                default :
                    $chars='ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
                    break;
            }
            
            while(strlen($password)<$len){
                $tmp =substr($chars,(mt_rand()%strlen($chars)),1);
                if(($is_numer <> 1 && is_numeric($tmp) && $tmp > 0 )|| $format == 'CHAR'){
                    $is_numer = 1;
                }
                if(($is_abc <> 1 && preg_match('/[a-zA-Z]/',$tmp)) || $format == 'NUMBER'){
                    $is_abc = 1;
                }
                $password.= $tmp;
            }
            if($is_numer <> 1 || $is_abc <> 1 || empty($password) ){
                $password = createCode($len,$format);
            }
            if($password!=''){
                
                $oneinfo=Db::name("agent_code")->field("uid")->where("code='{$password}'")->find();
                if(!$oneinfo){
                    return $password;
                }            
            }
            $password = createCode($len,$format);
            return $password;
        }
    /* 过滤字符 */
    function filterField($field)
    {
        $configpri = getConfigPri();

        $sensitive_field = $configpri[‘sensitive_field’];

        $sensitive = explode(",", $sensitive_field);
        $replace = array();
        $preg = array();
        foreach ($sensitive as $k => $v) {
            if ($v != '') {
                $re = '';
                $num = mb_strlen($v);
                for ($i = 0; $i < $num; $i++) {
                    $re .= '*';
                }
                $replace[$k] = $re;
                $preg[$k] = '/' . $v . '/';
            } else {
                unset($sensitive[$k]);
            }
        }

        return preg_replace($preg, $replace, $field);
    }

    /* 时间差计算 */
    function datetime($time)
    {
        $cha = time() – $time;
        $iz = floor($cha / 60);
        $hz = floor($iz / 60);
        $dz = floor($hz / 24);
        /* 秒 */
        $s = $cha % 60;
        /* 分 */
        $i = floor($iz % 60);
        /* 时 */
        $h = floor($hz / 24);
        /* 天 */

        if ($cha < 60) {
            return $cha . '秒前';
        } else if ($iz < 60) {
            return $iz . '分钟前';
        } else if ($hz < 24) {
            return $hz . '小时' . $i . '分钟前';
        } else if ($dz < 30) {
            return $dz . '天前';
        } else {
            return date("Y-m-d", $time);
        }
    }

    /* 时间差计算 */
    function datetimeNearby($time)
    {
        $cha = time() – $time;
        $iz = floor($cha / 60);
        $hz = floor($iz / 60);
        $dz = floor($hz / 24);
        /* 秒 */
        $s = $cha % 60;
        /* 分 */
        $i = floor($iz % 60);
        /* 时 */
        $h = floor($hz / 24);
        /* 天 */

        if ($cha < 300) {
            return T('Online');
        } else if ($iz < 30) {
            return T('Just online');
        } else if ($hz < 1) {
            return $i . T('minutes ago');
        } else if ($hz < 24) {
            return $hz . T('hour') . $i . T('minutes ago');
        } else if ($dz < 3) {
            return $dz . T('days ago');
        } else {
            return date("Y-m-d", $time);
        }
    }


    /**
     * @desc 根据两点间的经纬度计算距离
     * @param float $lat 纬度值
     * @param float $lng 经度值
     */
    function getDistance($lat1, $lng1, $lat2, $lng2)
    {
        $earthRadius = 6371000; //近似地球半径 单位 米
        /*
               Convert these degrees to radians
               to work with the formula
             */

        $lat1 = ($lat1 * pi()) / 180;
        $lng1 = ($lng1 * pi()) / 180;

        $lat2 = ($lat2 * pi()) / 180;
        $lng2 = ($lng2 * pi()) / 180;


        $calcLongitude = $lng2 – $lng1;
        $calcLatitude = $lat2 – $lat1;
        $stepOne = pow(sin($calcLatitude / 2), 2) + cos($lat1) * cos($lat2) * pow(sin($calcLongitude / 2), 2);
        $stepTwo = 2 * asin(min(1, sqrt($stepOne)));
        $calculatedDistance = $earthRadius * $stepTwo;

        $distance = $calculatedDistance / 1000;
        if ($distance < 10) {
            $rs = round($distance, 2);
        } else if ($distance > 1000) {
            $rs = '1000';
        } else {
            $rs = round($distance);
        }
        return $rs . 'km';
    }
    /* 去除emoji表情 */
    function filterEmoji($str)
    {
        $str = preg_replace_callback(
            '/./u',
            function (array $match) {
                return strlen($match[0]) >= 4 ? ” : $match[0];
            },
            $str);
        return $str;
    }

    /**
     *
     * curl post/get请求
     * @param $url string 请求地址
     * @param $vars array post请求的参数
     * @param $isJson bool 是否需要发送json数据类型的数据
     */
    function curlRequest($url, $vars, $isJson = false)
    {

        $ch = curl_init();
        $params[CURLOPT_URL] = $url;    //请求url地址
        $params[CURLOPT_HEADER] = false; //是否返回响应头信息
        $params[CURLOPT_RETURNTRANSFER] = true; //是否将结果返回
        $params[CURLOPT_FOLLOWLOCATION] = true; //是否重定向
        $params[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Windows NT 5.1; rv:9.0.1) Gecko/20100101 Firefox/9.0.1';

        $postfields = '';
        if (!$isJson) {
            foreach ($vars as $key => $value) {
                $postfields .= urlencode($key) . '=' . urlencode($value) . '&';
            }
        } else {
            $postfields = json_encode($vars);
        }
        $params[CURLOPT_POST] = true;
        $params[CURLOPT_POSTFIELDS] = $postfields;

        //解决方案一 禁用证书验证
        $params[CURLOPT_SSL_VERIFYPEER] = false;
        $params[CURLOPT_SSL_VERIFYHOST] = false;

        curl_setopt_array($ch, $params); //传入curl参数
        return curl_exec($ch); //执行
    }


    /* curl get请求 */
    function curl_get($url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // 跳过证书检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 0);  // 从证书中检查SSL加密算法是否存在
        $return_str = curl_exec($curl);
        curl_close($curl);
        return $return_str;
    }

    /* 检测文件后缀 */
    function checkExt($filename)
    {
        $config = array("jpg", "png", "jpeg");
        $ext = pathinfo(strip_tags($filename), PATHINFO_EXTENSION);

        return empty($config) ? true : in_array(strtolower($ext), $config);
    }

    /* 密码加密 */
    function setPass($pass)
    {
        $authcode = 'rCt52pF2cnnKNB3Hkp';
        $pass = "###" . md5(md5($authcode . $pass));
        return $pass;
    }

    /* 去除NULL 判断空处理 主要针对字符串类型*/
    function checkNull($checkstr)
    {
        $checkstr = trim($checkstr);
        $checkstr = urldecode($checkstr);
        if (get_magic_quotes_gpc() == 0) {
            $checkstr = addslashes($checkstr);
        }
        //$checkstr=htmlspecialchars($checkstr);
        //$checkstr=filterEmoji($checkstr);
        if (strstr($checkstr, 'null') || (!$checkstr && $checkstr != 0)) {
            $str = '';
        } else {
            $str = $checkstr;
        }
        return $str;
    }


    function Post($curlPost, $url)
    {
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HEADER, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_NOBODY, true);
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $curlPost);
        $return_str = curl_exec($curl);
        curl_close($curl);
        return $return_str;
    }

    function xml_to_array($xml)
    {
        $reg = "/<(\w+)[^>]*>([\\x00-\\xFF]*)<\\/\\1>/";
        if (preg_match_all($reg, $xml, $matches)) {
            $count = count($matches[0]);
            for ($i = 0; $i < $count; $i++) {
                $subxml = $matches[2][$i];
                $key = $matches[1][$i];
                if (preg_match($reg, $subxml)) {
                    $arr[$key] = xml_to_array($subxml);
                } else {
                    $arr[$key] = $subxml;
                }
            }
        }
        return $arr;
    }


    /* 密码检查 */
    function passcheck($user_pass)
    {
        /* 必须包含字母、数字 */
        $preg = '/^(?=.*[A-Za-z])(?=.*[0-9])[a-zA-Z0-9~!@&%#_]{6,20}$/';
        $isok = preg_match($preg, $user_pass);
        if ($isok) {
            return 1;
        }
        return 0;
    }

    /* 检验手机号 */
    function checkMobile($mobile)
    {
        $ismobile = preg_match("/^1[3|4|5|6|7|8|9]\d{9}$/", $mobile);
        if ($ismobile) {
            return 1;
        } else {
            return 0;
        }
    }

    /* 随机数 */
    function random($length = 6, $numeric = 0)
    {
        PHP_VERSION < '4.2.0' && mt_srand((double)microtime() * 1000000);
        if ($numeric) {
            $hash = sprintf('%0' . $length . 'd', mt_rand(0, pow(10, $length) – 1));
        } else {
            $hash = '';
            $chars = 'ABCDEFGHJKLMNPQRSTUVWXYZ23456789abcdefghjkmnpqrstuvwxyz';
            $max = strlen($chars) – 1;
            for ($i = 0; $i < $length; $i++) {
                $hash .= $chars[mt_rand(0, $max)];
            }
        }
        return $hash;
    }

    /**
     * 二维数组根据某个字段排序
     * @param array $array 要排序的数组
     * @param string $keys   要排序的键字段
     * @param string $sort  排序类型  SORT_ASC     SORT_DESC 
     * @return array 排序后的数组
     */
    function arraySort($array, $keys, $sort = SORT_ASC) {
        $keysValue = [];
        foreach ($array as $k => $v) {
            $keysValue[$k] = $v[$keys];
        }
        array_multisort($keysValue, $sort, $array);
        return $array;
    }


        /**
         * 生成唯一文件名称
         */
        function uuid()
        {
            $charid = md5(uniqid(mt_rand(), true));
            $hyphen = chr(45);
            $uuid = substr($charid, 0, 8) . $hyphen
                . substr($charid, 8, 4) . $hyphen
                . substr($charid, 12, 4) . $hyphen
                . substr($charid, 16, 4) . $hyphen
                . substr($charid, 20, 12);
            return $uuid;
        }
        
    /**
     * url的base64编码
     * @param $str string 编码字符串
     */
    function urlBase64Encode($str)
    {
        $find = array('+', '/');
        $replace = array('-', '_');
        return str_replace($find, $replace, base64_encode($str));
    }

    PHP Redis Geo 相关  函数 –开始
    /**
     * redis geo 添加
     * @param $key
     * @param $longitude
     * @param $latitude
     * @param $member
     */
    function geoAdd($key, $longitude, $latitude, $member)
    {
        $isexist = DI()->redis->geoadd($key, $longitude, $latitude, $member);
        return $isexist;
    }

    /**
     * geo 距离
     * @param $key
     * @param $member1
     * @param $member2
     * @param null $unit
     */
    function geoDist($key, $member1, $member2, $unit = null)
    {
        $isexist = DI()->redis->geodist($key, $member1, $member2, $unit);
        return $isexist;
    }

    /**
     * geo 取地理位置坐标
     * @param $key
     * @param mixed …$member
     */
    function geoHash($key, …$member)
    {
        $isexist = DI()->redis->geohash($key, …$member);
        return $isexist;
    }

    /**
     * geo 指定名称之间距离
     * @param string $key
     * @param string $member
     */
    function geoPos(string $key, string $member)
    {
        $isexist = DI()->redis->geopos($key, $member);
        return $isexist;
    }

    /**
     * geo 指定坐标中心范围内地点
     * @param $key
     * @param $longitude
     * @param $latitude
     * @param $radius
     * @param $unit
     * @param array|null $options
     */
    function geoRadius($key, $longitude, $latitude, $radius, $unit, array $options = null)
    {
        $isexist = DI()->redis->georadius($key, $longitude, $latitude, $radius, $unit, $options);
        return $isexist;
    }

    /**
     * geo 指定位置中心范围内地点
     * @param $key
     * @param $member
     * @param $radius
     * @param $units
     * @param array|null $options
     * @return array
     */
    function geoRadiusByMember($key, $member, $radius, $units, array $options = null)
    {
        $isexist = DI()->redis->georadiusbymember($key, $member, $radius, $units, $options);
        return $isexist;
    }

    PHP Redis Geo 相关  函数 — 结束

    PHP  Redis 链接 (π框架)– 开始


    /* Redis链接 */
    function connectionRedis()
    {
        $REDIS_HOST = DI()->config->get('app.REDIS_HOST');
        $REDIS_AUTH = DI()->config->get('app.REDIS_AUTH');
        $REDIS_PORT = DI()->config->get('app.REDIS_PORT');
        $redis = new Redis();
        $redis->pconnect($REDIS_HOST, $REDIS_PORT);
        $redis->auth($REDIS_AUTH);

        return $redis;
    }

    /* 设置缓存 */
    function setcache($key, $info)
    {
        $config = getConfigPri();
        if ($config[‘cache_switch’] != 1) {
            return 1;
        }

        DI()->redis->set($key, json_encode($info));
        DI()->redis->expire($key, $config[‘cache_time’] ?? 60);

        return 1;
    }

    /* 设置缓存 可自定义时间*/
    function setcaches($key, $info, $time = 0)
    {
        DI()->redis->set($key, json_encode($info));
        if ($time > 0) {
            DI()->redis->expire($key, $time);
        }

        return 1;
    }

    /* 获取缓存 */
    function getcache($key)
    {
        $config = getConfigPri();

        if ($config[‘cache_switch’] != 1) {
            $isexist = false;
        } else {
            $isexist = DI()->redis->Get($key);
        }

        return json_decode($isexist, true);
    }

    /* 获取缓存 不判断后台设置 */
    function getcaches($key)
    {

        $isexist = DI()->redis->Get($key);

        return json_decode($isexist, true);
    }

    /* 删除缓存 */
    function delcache($key)
    {
        $isexist = DI()->redis->del($key);
        return 1;
    }

    PHP  Redis 链接 (π框架)– 结束

     

  • linux redis-连接命令

    连接远程

    redis-cli -h 47.101.63.222 -p 56379

    连接本地

    redis-cli

    设置密码

    config set requirepass pass_123456

    获取密码

    config get requirepass

    登录

    auth pass_123456
  • PHP根据生日计算年龄两种方法(周岁)

    1、计算年龄
    functionhowOld($birth) {
            list($birthYear, $birthMonth, $birthDay) = explode('-', date('Y-m-d', $birth));
            list($currentYear, $currentMonth, $currentDay) = explode('-', date('Y-m-d'));
            $age = $currentYear – $birthYear – 1;
            if($currentMonth > $birthMonth || $currentMonth == $birthMonth && $currentDay >= $birthDay)
                $age++;
            return$age;
        }

    2、计算年龄(年月日)

        function datediffage($before, $after) {
         if ($before>$after) {
          $b = getdate($after);
          $a = getdate($before);
         }
         else {
          $b = getdate($before);
          $a = getdate($after);
         }
         $n = array(1=>31,2=>28,3=>31,4=>30,5=>31,6=>30,7=>31,8=>31,9=>30,10=>31,11=>30,12=>31);
         $y=$m=$d=0;
         if ($a[‘mday’]>=$b[‘mday’]) { //天相减为正
          if ($a[‘mon’]>=$b[‘mon’]) {//月相减为正
           $y=$a[‘year’]-$b[‘year’];$m=$a[‘mon’]-$b[‘mon’];
          }
          else { //月相减为负,借年
           $y=$a[‘year’]-$b[‘year’]-1;$m=$a[‘mon’]-$b[‘mon’]+12;
          }
          $d=$a[‘mday’]-$b[‘mday’];
         }
         else {  //天相减为负,借月
          if ($a[‘mon’]==1) { //1月,借年
           $y=$a[‘year’]-$b[‘year’]-1;$m=$a[‘mon’]-$b[‘mon’]+12;$d=$a[‘mday’]-$b[‘mday’]+$n[12];
          }
          else {
           if ($a[‘mon’]==3) { //3月,判断闰年取得2月天数
            $d=$a[‘mday’]-$b[‘mday’]+($a[‘year’]%4==0?29:28);
           }
           else {
            $d=$a[‘mday’]-$b[‘mday’]+$n[$a[‘mon’]-1];
           }
           if ($a[‘mon’]>=$b[‘mon’]+1) { //借月后,月相减为正
            $y=$a[‘year’]-$b[‘year’];$m=$a[‘mon’]-$b[‘mon’]-1;
           }
           else { //借月后,月相减为负,借年
            $y=$a[‘year’]-$b[‘year’]-1;$m=$a[‘mon’]-$b[‘mon’]+12-1;
           }
          }
         }
         return (string)$y;
        }

  • HTML5 FormData 方法介绍以及实现文件上传

     

    XMLHttpRequest 是一个浏览器接口,通过它,我们可以使得 Javascript 进行 HTTP (S) 通信。
    XMLHttpRequest 在现在浏览器中是一种常用的前后台交互数据的方式。2008年 2 月,
    XMLHttpRequest Level 2 草案提出来了,相对于上一代,它有一些新的特性,其中 FormData 就是
    XMLHttpRequest Level 2 新增的一个对象,利用它来提交表单、模拟表单提交,当然最大的优势就是可以上传二进制文件。下面就具体介绍一下如何利用 FormData 来上传文件。

    FormData 上传文件实例

    首先看一下formData的基本用法:FormData对象,可以把所有表单元素的namevalue组成一个queryString,提交到后台。只需要把 form 表单作为参数传入 FormData 构造函数即可:

    var form = document.getElementById("form1");
    var fd = new FormData(form);
    
     

    这样就可以直接通过ajaxsend() 方法将 fd 发送到后台。

    以下创建了一个表单 form,表单中除了普通的数据外,还有文件上传,我们直接将 form对象作为参数传入FormData对象:

    <form name="form1" id="form1">  
            <p>name:<input type="text" name="name" /></p>  
            <p>gender:<input type="radio" name="gender" value="1" />male <input type="radio" name="gender" value="2" />female</p>
            <p>stu-number:<input type="text" name="number" /></p>  
            <p>photo:<input type="file" name="photo" id="photo"></p>  
            <p><input type="button" name="b1" value="submit" onclick="fsubmit()" /></p>  
    </form>  
    <div id="result"></div>
    
     

    上述代码创建一个form,简单的填写一些信息,以及选择一张图片作为头像,设置一个div来存放返回的结果。
    这里写图片描述
    为了简便,我们还是采用jquery封装的ajax来向后台传输数据:

    function fsubmit() {
            var form=document.getElementById("form1");
            var fd =new FormData(form);
            $.ajax({
                 url: "server.php",
                 type: "POST",
                 data: fd,
                 processData: false,  // 告诉jQuery不要去处理发送的数据
                 contentType: false,   // 告诉jQuery不要去设置Content-Type请求头
                 success: function(response,status,xhr){
                    console.log(xhr);
                    var json=$.parseJSON(response);
                    var result = '';
                    result +="个人信息:<br/>name:"+json['name']+"<br/>gender:"+json['gender']+"<br/>number:"+json['number'];
                     result += '<br/>头像:<img src="' + json['photo'] + '" height="100" style="border-radius: 50%;" />';
                     $('#result').html(result);
                 }
            });
            return false;
        }
    
     

    上述代码中的 server.php 是服务器端的文件,接收ajax请求,并将接收结果返回,具体代码如下:

    <?php
    
    $name = isset($_POST['name'])? $_POST['name'] : '';  
    $gender = isset($_POST['gender'])? $_POST['gender'] : '';
    $number = isset($_POST['number'])? $_POST['number'] : '';  
    $filename = time().substr($_FILES['photo']['name'], strrpos($_FILES['photo']['name'],'.'));  
    $response = array();
    
    if(move_uploaded_file($_FILES['photo']['tmp_name'], $filename)){  
        $response['isSuccess'] = true;  
        $response['name'] = $name;  
        $response['gender'] = $gender;
        $response['number'] = $number;  
        $response['photo'] = $filename;  
    }else{  
        $response['isSuccess'] = false;  
    }  
    echo json_encode($response);
    ?>
    
    

    填写好信息后,点击 submit,页面中能得到以下效果,去服务器端对应的文件夹下也能发现上传的图片。

    这里写图片描述
    如果你是原生 JavaScript 爱好者,当然一样能实现以上功能,下面是简单的JavaScript实现代码:

    function fsubmit() {
        var form=document.getElementById("form1");
        var formData=new FormData(form);
        alert(formData.name);
        var oReq = new XMLHttpRequest();
        oReq.onreadystatechange=function(){
          if(oReq.readyState==4){
            if(oReq.status==200){
                console.log(typeof oReq.responseText);
                var json=JSON.parse(oReq.responseText);
                var result = '';
                result +="个人信息:<br/>name:"+json['name']+"<br/>gender:"+json['gender']+"<br/>number:"+json['number'];
                 result += '<br/>头像:<img src="' + json['photo'] + '" height="50" style="border-radius: 50%;" />';
    
                 $('#result').html(result);
            }
          }
        };
        oReq.open("POST", "server.php");
        oReq.send(formData); 
        return false;
    }
    
    FormData 对象方法介绍

    FormData 除了上面的创建新对象时直接将 form 作为参数传入外,还有其他的功能。网上大部分关于 FormData 介绍的文章都只提到了append()方法,那么FormData 对象到底有些什么方法呢?我们console 一下就知道:
    这里写图片描述
    console 之后我们有重大的发现,FormData 对象竟然有这么方法,所以还是自己测试才能发现真相,下面就对这些方法一一进行讲解:

    1、append()

    append()方法用于向 FormData 对象中添加键值对:

    fd.append('key1',"value1");
    fd.append('key2',"value2");
    
     

    fdFormData 对象,可以新建的空的对象,也可以是已经包含 form 表单或其他键值对。

    2、set()

    设置对应的键 key 对应的值 value(s)

    fd.set('key1',"value1");
    fd.set('key2',"value2");
    
    

    看起来跟append() 方法有点类似,这两者的区别就是,当指定的 key 值存在时,append()方法是将新增的添加的所以的键值对最后,而set()方法将会覆盖前面的设置的键值对。还是通过实例来对比,我们在前面的 form 的基础上 append()set() 新的键值对:

    fd.append('name',"will");
    
     

    有两个keyname的键值对:
    这里写图片描述

    fd.set('name',"will");
    
     

     

    只有一个keyname的键值对:
    这里写图片描述
    以上就是 append()set() 的区别。如果设置的key值不存在,那么两者的效果是一样的。

    3、delete()
    接收一个参数,表示你要删除的 key 值的名字,如果有多个相同 key 值,会一并删除:

    fd.append('name','will');
    fd.delete('name');
    
    
     

    form 中的 name 信息以及通过append() 新增的name 的信息都被删除了。

    4、get()getAll()
    接收一个参数,表示需要查找的 key 的名称,返回第一个该 key 对应的 value 值。如果有多个相同的 key, 而且要返回所有的这个 key 对应的 value 值。

    同样以上面的 form 表单为基础:

    fd.append('name','will');
    console.log(fd.get('name')); // sean
    
     
    fd.append('name','will');
    console.log(fd.getAll('name')); // ["sean", "will"]
    
     

    5、has()

    该方法也接收一个参数,同样是 key 的名称,返回一个Boolean 值, 用来判断FormData 对象是否含有该 key。以上面的form为例:

    console.log(fd.has('name')); // true
    console.log(fd.has('Name')); // false
    
     

    6、keys()

    该方法不需要接收参数,返回一个迭代器,通过这个迭代器,我们可以遍历FormData 对象中所有的 key。以上面的form为例:

    for (var key of fd.keys()) 
    {
        console.log(key); 
    }
    
    结果为:
    name
    gender
    number
    photo
    
     

    7、values()
    有遍历 key 的迭代,当然也就少不了遍历 value 的迭代器了。values()就是遍历value 的迭代器,用法与 keys() 类似:

    for (var value of fd.values()) 
    {
         console.log(value); 
    }
    
    结果:

    这里写图片描述

    8、entries()

    有遍历 key 的迭代器,也有遍历 value 的迭代器,为何不搞一个两者一起的呢!entries()就是返回一个包含键值对的迭代器:

    for(var pair of fd.entries()) 
    {
       console.log(pair[0]+ ', '+ pair[1]); 
    }
    
    结果:

    这里写图片描述

    FormData兼容性问题

    由于 FormDataXMLHttpRequest Level 2 新增的接口,现在 低于IE10IE浏览器不支持 FormData ,至于 上面介绍的 FormData 对象的方法经过测试,在 IE 浏览器中都不支持,具体的各大浏览器的支持情况可以参照下图:
    这里写图片描述

     
  • tp5主从数据库设置读写分离

     
    // 数据库类型
        'type'            => 'mysql',
        // 服务器地址
        'hostname'        => '192.168.0.5,192.168.0.6',
        // 数据库名
        'database'        => 'test',
        // 用户名
        'username'        => 'root,root',
        // 密码
        'password'        => 'test,test',
        // 端口
        'hostport'        => '3306,3306',
        // 连接dsn
        'dsn'             => '',
        // 数据库连接参数
        'params'          => [],
        // 数据库编码默认采用utf8
        'charset'         => 'utf8,utf8',
        // 数据库表前缀
        'prefix'          => 'tp_',
        // 数据库调试模式
        'debug'           => true,
        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
        'deploy'          => 1,
        // 数据库读写是否分离 主从式有效
        'rw_separate'     => true,
        // 读写分离后 主服务器数量
        'master_num'      => 1,
        // 指定从服务器序号
        'slave_no'        => '',
        // 是否严格检查字段是否存在
        'fields_strict'   => true,
        // 数据集返回类型
        'resultset_type'  => 'array',
        // 自动写入时间戳字段
        'auto_timestamp'  => false,
        // 时间字段取出后的默认时间格式
        'datetime_format' => 'Y-m-d H:i:s',
        // 是否需要进行SQL性能分析
        'sql_explain'     => false,
     

    主要配置参数:

     
    // 数据库调试模式
        'debug'           => true,
        // 数据库部署方式:0 集中式(单一服务器),1 分布式(主从服务器)
        'deploy'          => 1,
        // 数据库读写是否分离 主从式有效
        'rw_separate'     => true,
        // 读写分离后 主服务器数量
        'master_num'      => 1,
        // 指定从服务器序号,可以默认不填写
        'slave_no'        => '',
     

    以下配置参数均为前主后从

     
     // 服务器地址
        'hostname'        => '192.168.0.5,192.168.0.6',
        // 数据库名
        'database'        => 'test',
        // 用户名
        'username'        => 'root,root',
        // 密码
        'password'        => 'test,test',
        // 端口
        'hostport'        => '3306,3306',
     

     

  • 通过FormData实现上传文件

    通过FormData实现上传文件

    html代码

    index.html

    <!DOCTYPE html>  
    <html xmlns="http://www.w3.org/1999/html">  
    <head>  
        <meta http-equiv="content-type" content="text/html; charset=utf-8"/>
    <html>  
    <head>  
    <title></title>  
    
    </head>  
      
    <body>  
    <form enctype="multipart/form-data" id="uploadImg">
        上传文件:  
        <input name="file" type="file" id="file"> 
    </form>
    </body>  
    </html>
    <script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
    <script>
        $(function(){
            $('input[type="file"]').on('change', function(){
                var file = this.files[0];
                var formData = new FormData($('#uploadImg')[0]);
                formData.append('file', file);
                console.log(formData.get('file'))
                $.ajax({
                    url: 'upload.php',
                    type: 'POST',
                    cache: false,
                    data: formData,
                    //dataType: 'json',
                    //async: false,
                    processData: false,    //不需要对数据做任何预处理
                    contentType: false,    //不设置数据格式
                }).done(function(res) {
                    console.log(res)
                }).fail(function(res) {
                    console.log(res)
                });
            });
        })
    </script>
    

    后端代码(以php为例)

    upload.php

    <?php
        //print_r($_FILES);    
        $uptypes=array(  
            'image/jpg',  
            'image/jpeg',  
            'image/png',  
            'image/pjpeg',  
            'image/gif',  
            'image/bmp',  
            'image/x-png'  
        );
    
        $max_file_size=200000000;     //上传文件大小限制, 单位BYTE
        
        $file=$_FILES["file"];
        $fileName=$file["name"];
        $filetype = $file["type"];
        $filesize = $file["size"];
        
        if(!in_array($filetype, $uptypes)){            // 文件类型判断
            echo "文件类型不符!";
            exit;
        }
        if($filesize > $max_file_size){                // 文件大小判断
            echo "文件太大!";
            exit;    
        }
        if (!is_dir("image/")) {                    //创建路径
            mkdir("image/");
        }
        $url = "image/";
        //当文件存在
        if (file_exists($url.$fileName)) {
            //echo $fileName." already exists.";
            echo $url.$fileName;
        }else{//当文件不存在
            $url=$url.$fileName;
            move_uploaded_file($_FILES["file"]["tmp_name"],$url);
            echo $url;
        }
    ?>
    

    注意事项

    • 在PHP中通过print_r($_FILES)打印时,有时候formData里面的参数type会为空,而在前端打印的formData.get('file')里是有type的值的,原因是PHP导入文件(我是导的图片)有大小限制
      解决方法:在php.ini中,搜索upload_max_filesize(默认为2M),修改这个值,重启服务器即可。

    • 在通过ajax进行数据请求时,console.log(formData)对象为空,而且在append后还是为空,是因为属性不是直接挂载在你这个FormData,可以通过get方法进行获取。

    • 在一般情况下使用ajax请求,processData(默认为true)不需要设置,但是当使用fromdata上传文件时,发送的对象不需要转化为对象,所以必须设置为false。

     
  • 国际化(i18n) 各国语言缩写

    internationalization (国际化)简称:i18n,因为在i和n之间还有18个字符,localization(本地化 ),简称L10n。 一般用语言_地区的形式表示一种语言,如:zh_CN表示简体中文。

     

    国际化开发的各国语言标识

     

    **国家地区**            **语言标识**
    
    简体中文(中国)        zh_CN
    繁体中文(台湾地区)     zh_TW
    繁体中文(香港)        zh_HK
    英语(香港)            en_HK
    英语(美国)            en_US
    英语(英国)            en_GB
    英语(全球)    en_WW
    英语(加拿大)    en_CA
    英语(澳大利亚)    en_AU
    英语(爱尔兰)    en_IE
    英语(芬兰)    en_FI
    芬兰语(芬兰)    fi_FI
    英语(丹麦)    en_DK
    丹麦语(丹麦)    da_DK
    英语(以色列)    en_IL
    希伯来语(以色列)    he_IL
    英语(南非)    en_ZA
    英语(印度)    en_IN
    英语(挪威)    en_NO
    英语(新加坡)    en_SG
    英语(新西兰)    en_NZ
    英语(印度尼西亚)    en_ID
    英语(菲律宾)    en_PH
    英语(泰国)    en_TH
    英语(马来西亚)    en_MY
    英语(阿拉伯)    en_XA
    韩文(韩国)    ko_KR
    日语(日本)    ja_JP
    荷兰语(荷兰)    nl_NL
    荷兰语(比利时)    nl_BE
    葡萄牙语(葡萄牙)    pt_PT
    葡萄牙语(巴西)    pt_BR
    法语(法国)    fr_FR
    法语(卢森堡)    fr_LU
    法语(瑞士)    fr_CH
    法语(比利时)    fr_BE
    法语(加拿大)    fr_CA
    西班牙语(拉丁美洲)    es_LA
    西班牙语(西班牙)    es_ES
    西班牙语(阿根廷)    es_AR
    西班牙语(美国)    es_US
    西班牙语(墨西哥)    es_MX
    西班牙语(哥伦比亚)    es_CO
    西班牙语(波多黎各)    es_PR
    德语(德国)    de_DE
    德语(奥地利)    de_AT
    德语(瑞士)    de_CH
    俄语(俄罗斯)    ru_RU
    意大利语(意大利)    it_IT
    希腊语(希腊)    el_GR
    挪威语(挪威)    no_NO
    匈牙利语(匈牙利)    hu_HU
    土耳其语(土耳其)    tr_TR
    捷克语(捷克共和国)    cs_CZ
    斯洛文尼亚语    sl_SL
    波兰语(波兰)    pl_PL
    瑞典语(瑞典)    sv_SE
    西班牙语 (智利)    es_CL

     

    来源:https://www.cnblogs.com/exmyth/p/11687034.html

  • CentOS7 yum 安装git过程

     

     

    安装git

    yum install git

    检查git版本

    git –version

    在这里插入图片描述

    发现不是较新的版本或者是我们想要的版本

    移除该版本git

    yum remove git

    下载编译工具

    yum -y groupinstall Development Tools

    在这里插入图片描述

    下载依赖包

    yum -y install zlib-devel perl-ExtUtils-MakeMaker asciidoc xmlto openssl-devel

    在这里插入图片描述

    下载 Git 最新版本的源代码

    wget https://www.kernel.org/pub/software/scm/git/git-2.9.5.tar.gz

    登录https://github.com/git/git/releases查看git的最新版。不要下载带有-rc的,因为它代表了一个候选发布版本。
    在这里插入图片描述

    解压

    tar -zxvf git-2.9.5.tar.gz

    在这里插入图片描述

    进入目录配置

    cd git-2.9.5
    ./configure –prefix=/usr/local/git

    在这里插入图片描述

    安装

    make && make install

    在这里插入图片描述

    配置全局路径

    export PATH="/usr/local/git/bin:$PATH"
    source /etc/profile

    在这里插入图片描述
    以上即为安装的全部步骤。

    后续使用中,遇到错误
    Unable to find remote helper for ‘https’
    解决方法:
    将 /usr/libexec/git-core 纳入 PATH,至少在使用 git 之前,设置一下PATH

    PATH=$PATH:/usr/libexec/git-core

    或直接在 /etc/profile 中修改。

    配置环境变量的备用方案

    [root@bogon git-2.3.0]# echo "export PATH=$PATH:/usr/local/git/bin" > /etc/profile.d/git.sh
    [root@bogon git-2.3.0]# source /etc/profile.d/git.sh
    [root@bogon git-2.3.0]# git --version