zoukankan      html  css  js  c++  java
  • PHP文件那些事儿

    0、参考资料

    1、PHP上传文件

    PHP后台获取上传文件,利用全局变量$_FILES获取上传文件。

    $schemaTmpFile = $_FILES['owndata_schema'];
    # 文件属性
    array(5) {
      'name' =>
      string(12) "desc-foo.csv"
      'type' =>
      string(24) "application/vnd.ms-excel"
      'tmp_name' =>
      string(19) "/data/tmp/php8zDKJi"
      'error' =>
      int(0)
      'size' =>
      int(180)
    }
    

    文件属性:

    • 1、 name: 下标指的是上传文件的文件名。
    • 2、**type:下标指的是上传文件的类型。 **
    • 3、 **tmp_name: 下标指的是上传的文件在服务器端存放的临时文件名。 **
    • 4、**error: 下标是上传文件错误的表示,可用于检测文件是否上传,以便找到错误的原因。 **
    • 5、**size: 下标是上传文件的大小,单位是字节。 **

    2、PHP拉取远程文件

    如果文件是远程文件,首先需要判断远程文件是否真的存在。

    ① 判断远程文件是否存在

    curl经过验证是最为靠谱的方法。

        /**
         * 判断远程文件是否存在
         * @param $remoteFile
         * @return bool
         */
        public function remoteFileExists($remoteFile)
        {
            $curl = curl_init($remoteFile);
            
    // CURLOPT_NOBODY设置为true,因为不需要真正的读取文件内容,只需要判断是否存在
            curl_setopt($curl, CURLOPT_NOBODY, true);
            $result = curl_exec($curl);
            
            $ret = false;
            
            //if request did not fail
            if ($result !== false) {
                //if request was ok, check response code
                $statusCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
                if ($statusCode == 200) {
                    $ret = true;
                }
            }
            
            curl_close($curl);
            return $ret;
        }
    

    ② 获取远程文件大小

        /**
         * 获取远程文件大小
         * @param $remoteFile
         * @return mixed
         */
        public static function getRemoteFileSize($remoteFile)
        {
            $headerInfo = get_headers($remoteFile,true);
            return $headerInfo['Content-Length'];
        }
    

    get_headers(): 返回一个数组,包含有服务器响应一个 HTTP 请求所发送的标头。可以从头部信息的Content-Length字段获取文件大小。
    demo示例如下:

    $remoteFile = "http://km.oa.com/files/photos/pictures/201801/1516586415_55_w157_h211.jpg";
    $headerInfo = get_headers($remoteFile,true);
    var_dump($headerInfo);
    // 打印结果如下:
    array(11) {
      [0] =>
      string(15) "HTTP/1.1 200 OK"
      'Server' =>
      string(12) "nginx/1.10.1"
      'Date' =>
      string(29) "Wed, 24 Jan 2018 09:04:03 GMT"
      'Content-Type' =>
      string(10) "image/jpeg"
      'Content-Length' =>
      string(5) "15893"
      'Last-Modified' =>
      string(29) "Mon, 22 Jan 2018 02:00:14 GMT"
      'Connection' =>
      string(5) "close"
      'ETag' =>
      string(15) ""5a6545ae-3e15""
      'Expires' =>
      string(29) "Fri, 23 Feb 2018 09:04:03 GMT"
      'Cache-Control' =>
      string(15) "max-age=2592000"
      'Accept-Ranges' =>
      string(5) "bytes"
    }
    

    3、下载远程文件

    下载远程文件思路:

    • 1、获取文件内容,然后写到服务器本地地址。
    • 2、大文件,需要分片读取。
        /**
         * 下载文件&存储文件到磁盘
         * @param string $fileUrl
         * @return bool|string
         */
        protected function downFile($fileUrl = '')
        {
            $time = time();
            $taskDir = FILE_UPLOAD_BASE_PATH . '/owndata_schema';
        
            if (!is_dir($taskDir)) {
                if (mkdir($taskDir)) {
                    Log::info("create dir succ:" . $taskDir);
                } else {
                    Log::info("create dir fail:" . $taskDir);
                    $this->err_msg = "文件路径创建失败";
                    return false;
                }
            }
            
            $pathParts = pathinfo($fileUrl);
            $fileName = $pathParts['basename'];
            $fileName = $time . '_' . $fileName;
            $saveFileUrl = $taskDir . '/' .$fileName;
            // 下面核心代码
    	    // fopen()可以读入大文件,每次可以指定读取一部分的内容。在操作大文件的时候也很有用。
            $rfp = fopen($fileUrl, "rb");
            $wfp = fopen($saveFileUrl, "a+");
            while (!feof($rfp)) {
                $tmpContent = fread($rfp, 1024*8);
                fwrite($wfp, $tmpContent);
            }
            fclose($rfp);
            fclose($wfp);
            
            // 返回磁盘临时存储文件路径
            return $saveFileUrl;
        }
    

    总结:利用PHP下载文件时,应该要注重场景。如果本身只是几个小文件被下载,那么使用PHP下载比较好;但是如果PHP要承受大量下载请求,这时下载文件就不该交给PHP做,应该采取异步方式进行下载。

    4、文件编码

    获取上传文件或者远程文件时,有个时候需要对文件的编码进行处理。

    ① 获取文件编码函数

    mb_detect_encoding()

    ② 针对UTF-8文件,去掉文件BOM头

        /**
         * UTF8 去掉文本中的 bom头
         * @param $contents
         * @return mixed
         */
        private function clearBom($contents)
        {
            $bom = chr(239) . chr(187) . chr(191);
            return str_replace($bom, '', $contents);
        }
        
        /**
         * 文件编码格式处理
         * @param $fileUrl
         */
        private function clearFileBom($fileUrl)
        {
            $encodeList = ['GBK', 'UTF-8'];
            $contents = file_get_contents($fileUrl);
            $encode = mb_detect_encoding($contents, $encodeList);
            if ($encode == 'UTF-8') {
                $contents = $this->clearBom($contents);
                file_put_contents($fileUrl, $contents);
            } else {
                $contents = StringUtil::gbkToutf8($contents);
                file_put_contents($fileUrl, $contents);
            }
        }
    
  • 相关阅读:
    JQuery扩展方法
    RabbitMQ消息机制广播分发
    RabbitMQ消息机制单人分发
    对函数的参数求和
    ajax jsonp
    绑定函数bind()
    this 指向
    DOM兼容
    命名空间 namespace
    开始看编写高质量的代码
  • 原文地址:https://www.cnblogs.com/jaspersong/p/8343036.html
Copyright © 2011-2022 走看看