利用WebUploader实现大文件上传和视频上传

文件上传是网站开发必不可少的,常见的有图片上传。但是大文件和视频上传不常见。这里我将自己写的视频上传demo贴出来供大家参考:

利用是最新的WebUploader插件请 下载使用最新版即可

js代码

[javascript] view plain copy

  1. _extensions ='3gp,mp4,rmvb,mov,avi,m4v';  
  2.     _mimeTypes ='video/*,audio/*,application/*';  
  3.   
  4. $(function(){              
  5.     var chunkSize = 500 * 1024;        //分块大小  
  6.     var uniqueFileName = null;          //文件唯一标识符  
  7.     var md5Mark = null;  
  8.   
  9.     // var _backEndUrl = '';  
  10.   
  11.     WebUploader.Uploader.register({  
  12.         "before-send-file": "beforeSendFile"  
  13.         , "before-send": "beforeSend"  
  14.         , "after-send-file": "afterSendFile"  
  15.     }, {  
  16.         beforeSendFile: function(file){  
  17.             console.log(file);  
  18.             //秒传验证  
  19.             var task = new $.Deferred();  
  20.             var start = new Date().getTime();  
  21.             (new WebUploader.Uploader()).md5File(file, 0, 10*1024*1024).progress(function(percentage){  
  22.             }).then(function(val){  
  23.   
  24.                 md5Mark = val;  
  25.                 _userInfo.md5 = val;  
  26.   
  27.                 $.ajax({  
  28.                     type: "POST",  
  29.                     url: _backEndUrl,  
  30.                     data: {  
  31.                         status: "md5Check",  
  32.                         md5: val  
  33.                     },  
  34.                     cache: false,  
  35.                     timeout: 1000, //todo 超时的话,只能认为该文件不曾上传过  
  36.                     dataType: "json"  
  37.                 }).then(function(data, textStatus, jqXHR){  
  38.   
  39.                     if(data.ifExist){   //若存在,这返回失败给WebUploader,表明该文件不需要上传  
  40.                         task.reject();  
  41.   
  42.                         uploader.skipFile(file);  
  43.                         file.path = data.path;  
  44.                         UploadComlate(file);  
  45.                     }else{  
  46.                         task.resolve();  
  47.                         //拿到上传文件的唯一名称,用于断点续传  
  48.                         uniqueFileName = md5(_userInfo.openid+_userInfo.time);  
  49.                     }  
  50.                 }, function(jqXHR, textStatus, errorThrown){    //任何形式的验证失败,都触发重新上传  
  51.                     task.resolve();  
  52.                     //拿到上传文件的唯一名称,用于断点续传  
  53.                     uniqueFileName = md5(_userInfo.openid+_userInfo.time);  
  54.                 });  
  55.             });  
  56.             return $.when(task);  
  57.         }  
  58.         , beforeSend: function(block){  
  59.             //分片验证是否已传过,用于断点续传  
  60.             var task = new $.Deferred();  
  61.             $.ajax({  
  62.                 type: "POST"  
  63.                 , url: _backEndUrl  
  64.                 , data: {  
  65.                     status: "chunkCheck"  
  66.                     , name: uniqueFileName  
  67.                     , chunkIndex: block.chunk  
  68.                     , size: block.end - block.start  
  69.                 }  
  70.                 , cache: false  
  71.                 , timeout: 1000 //todo 超时的话,只能认为该分片未上传过  
  72.                 , dataType: "json"  
  73.             }).then(function(data, textStatus, jqXHR){  
  74.                 if(data.ifExist){   //若存在,返回失败给WebUploader,表明该分块不需要上传  
  75.                     task.reject();  
  76.                 }else{  
  77.                     task.resolve();  
  78.                 }  
  79.             }, function(jqXHR, textStatus, errorThrown){    //任何形式的验证失败,都触发重新上传  
  80.                 task.resolve();  
  81.             });  
  82.   
  83.             return $.when(task);  
  84.         }  
  85.         , afterSendFile: function(file){  
  86.             var chunksTotal = 0;  
  87.             if((chunksTotal = Math.ceil(file.size/chunkSize)) > 1){  
  88.                 //合并请求  
  89.                 var task = new $.Deferred();  
  90.                 $.ajax({  
  91.                     type: "POST"  
  92.                     , url: _backEndUrl  
  93.                     , data: {  
  94.                         status: "chunksMerge"  
  95.                         , name: uniqueFileName  
  96.                         , chunks: chunksTotal  
  97.                         , ext: file.ext  
  98.                         , md5: md5Mark  
  99.                     }  
  100.                     , cache: false  
  101.                     , dataType: "json"  
  102.                 }).then(function(data, textStatus, jqXHR){  
  103.   
  104.                     //todo 检查响应是否正常  
  105.   
  106.                     task.resolve();  
  107.                     file.path = data.path;  
  108.                     UploadComlate(file);  
  109.   
  110.                 }, function(jqXHR, textStatus, errorThrown){  
  111.                     task.reject();  
  112.                 });  
  113.   
  114.                 return $.when(task);  
  115.             }else{  
  116.                 UploadComlate(file);  
  117.             }  
  118.         }  
  119.     });  
  120.   
  121.     var uploader = WebUploader.create({  
  122.         swf: "./Uploader.swf",  
  123.         server: _backEndUrl,     //服务器处理文件的路径  
  124.         pick: "#picker",        //指定选择文件的按钮,此处放的是id  
  125.         resize: false,   
  126.         dnd: "#theList",        //上传文件的拖拽容器(即,如果选择用拖拽的方式选择文件进行上传,应该要把文件拖拽到的区域容器)  
  127.         paste: document.body,   //[可选] [默认值:undefined]指定监听paste事件的容器,如果不指定,不启用此功能。此功能为通过粘贴来添加截屏的图片。建议设置为document.body  
  128.         disableGlobalDnd: true, //[可选] [默认值:false]是否禁掉整个页面的拖拽功能,如果不禁用,图片拖进来的时候会默认被浏览器打开。  
  129.         compress: false,  
  130.         prepareNextFile: true,   
  131.         chunked: true,   
  132.         chunkSize: chunkSize,  
  133.         chunkRetry: 2,    //[可选] [默认值:2]如果某个分片由于网络问题出错,允许自动重传多少次?  
  134.         threads: true,      //[可选] [默认值:3] 上传并发数。允许同时最大上传进程数。  
  135.         formData: function(){return $.extend(true, {}, _userInfo);},   
  136.         fileNumLimit: 1,   
  137.         fileSingleSizeLimit: 50 * 1024 * 1024,// 限制在50M  
  138.         duplicate: true,  
  139.         accept: {        
  140.             title: '大文件上传',  //文字描述  
  141.             extensions: _extensions,     //允许的文件后缀,不带点,多个用逗号分割。,jpg,png,  
  142.             mimeTypes: _mimeTypes,      //多个用逗号分割。image/*,  
  143.         },  
  144.     });  
  145.   
  146.     /**  
  147.      * 验证文件格式以及文件大小  
  148.      */  
  149.     uploader.on("error",function (type,handler){  
  150.         if (type=="Q_TYPE_DENIED"){  
  151.             swal({  
  152.                 title:'',  
  153.                 text: '请上传MP4格式的视频~',  
  154.                 type: "warning",  
  155.                 confirmButtonColor: "#DD6B55",  
  156.                 confirmButtonText: "我知道了",  
  157.             });  
  158.         }else if(type=="F_EXCEED_SIZE"){  
  159.             swal({  
  160.                 title:'',  
  161.                 text: '视频大小不能超过50M哦~',  
  162.                 type: "warning",  
  163.                 confirmButtonColor: "#DD6B55",  
  164.                 confirmButtonText: "我知道了",  
  165.             });  
  166.         }  
  167.     });  
  168.   
  169.     uploader.on("fileQueued", function(file){  
  170.         $('#theList').show();  
  171.         $("#theList").append('<li id="'+file.id+'" class="upload_li">' +  
  172.             ' <img /> <span class="file_name upload_li">'+file.name+'</span></li><li class="upload_li"><span class="itemUpload weui-btn weui-btn_mini weui-btn_primary">上传</span><span class="itemStop weui-btn weui-btn_mini weui-btn_default">暂停</span><span class="itemDel weui-btn weui-btn_mini weui-btn_warn">删除</span></li><li class="upload_li">' +  
  173.             '<div id="percentage'+file.id+'" class="percentage"><div class="weui-progress__bar"><div class="weui-progress__inner-bar js_progress" style="width: 0%;"></div> <b id="pers"></b> </div></div>' +  
  174.         '</li>');  
  175.           
  176.         var $img = $("#" + file.id).find("img");  
  177.           
  178.         uploader.makeThumb(file, function(error, src){  
  179.             if(error){  
  180.                 $img.replaceWith("<span class='no_view'>视频暂不能预览</span>");  
  181.             }  
  182.   
  183.             $img.attr("src", src);  
  184.         });  
  185.           
  186.     });  
  187.       
  188.     $("#theList").on("click", ".itemUpload", function(){  
  189.         uploader.upload();  
  190.   
  191.         //"上传"-->"暂停"  
  192.         $(this).hide();  
  193.         $(".itemStop").css('display','inline-block');  
  194.         $(".itemStop").show();  
  195.     });  
  196.   
  197.     $("#theList").on("click", ".itemStop", function(){  
  198.         uploader.stop(true);  
  199.   
  200.         //"暂停"-->"上传"  
  201.         $(this).hide();  
  202.         $(".itemUpload").show();  
  203.     });  
  204.   
  205.     //todo 如果要删除的文件正在上传(包括暂停),则需要发送给后端一个请求用来清除服务器端的缓存文件  
  206.     $("#theList").on("click", ".itemDel", function(){  
  207.         uploader.removeFile($('.upload_li').attr("id"));    //从上传文件列表中删除  
  208.   
  209.         $('.upload_li').remove();   //从上传列表dom中删除  
  210.     });  
  211.       
  212.     uploader.on("uploadProgress", function(file, percentage){  
  213.         $(".percentage").find('.js_progress').css("width",percentage * 100 + "%");  
  214.         $(".percentage").find('#pers').text(parseInt(percentage * 100) + "%");  
  215.     });  
  216.   
  217.     function UploadComlate(file){  
  218.         console.log(file);  
  219.         if(file && file.name){  
  220.             $('#vedio').val(file.name);  
  221.             $(".percentage").find('#pers').html("<span style='color:green;'>上传完毕</span>");  
  222.             $(".itemStop").hide();  
  223.             $(".itemUpload").hide();  
  224.             $(".itemDel").hide();  
  225.         }else{  
  226.             $(".percentage").find('#pers').html("<span style='color:red;'>上传失败,请您检查网络状况~</span>");  
  227.             $(".itemStop").hide();  
  228.             $(".itemUpload").hide();  
  229.         }  
  230.   
  231.     }  
  232.   
  233. })  


 

PHP控制器

[php] view plain copy

  1. public function vupload(){  
  2.         set_time_limit (0);  
  3.         //关闭缓存  
  4.         header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");  
  5.         header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");  
  6.         header("Cache-Control: no-store, no-cache, must-revalidate");  
  7.         header("Cache-Control: post-check=0, pre-check=0", false);  
  8.         header("Pragma: no-cache");  
  9.   
  10.         $ip_path = './uploads/'.$_SESSION['userinfo']['id'];  
  11.         $save_path = 'uploads/'.$_SESSION['userinfo']['id'];  
  12.         $uploader =  new \Org\Util\Vupload;  
  13.         $uploader->set('path',$ip_path);  
  14.         //用于断点续传,验证指定分块是否已经存在,避免重复上传  
  15.         if(isset($_POST['status'])){  
  16.             if($_POST['status'] == 'chunkCheck'){  
  17.                 $target =  $ip_path.'/'.$_POST['name'].'/'.$_POST['chunkIndex'];  
  18.                 if(file_exists($target) && filesize($target) == $_POST['size']){  
  19.                     die('{"ifExist":1}');  
  20.                 }  
  21.                 die('{"ifExist":0}');  
  22.   
  23.             }elseif($_POST['status'] == 'md5Check'){  
  24.   
  25.                 //todo 模拟持久层查询  
  26.                 $dataArr = array(  
  27.                     'b0201e4d41b2eeefc7d3d355a44c6f5a' => 'kazaff2.jpg'  
  28.                 );  
  29.   
  30.                 if(isset($dataArr[$_POST['md5']])){  
  31.                     die('{"ifExist":1, "path":"'.$dataArr[$_POST['md5']].'"}');  
  32.                 }  
  33.                 die('{"ifExist":0}');  
  34.             }elseif($_POST['status'] == 'chunksMerge'){  
  35.   
  36.                 if($path = $uploader->chunksMerge($_POST['name'], $_POST['chunks'], $_POST['ext'])){  
  37.                     //todo 把md5签名存入持久层,供未来的秒传验证  
  38.                     session('video_path', $save_path.'/'.$path);  
  39.                     die('{"status":1, "path": "'.$save_path.'/'.$path.'"}');  
  40.                 }  
  41.                 die('{"status":0}');  
  42.             }  
  43.         }  
  44.   
  45.         if(($path = $uploader->upload('file', $_POST)) !== false){  
  46.             if(!session('video_path')){  
  47.                 session('video_path', $save_path.'/'.$path);  
  48.             }  
  49.             die('{"status":1, "path": "'.$save_path.'/'.$path.'"}');  
  50.         }  
  51.         die('{"status":0}');  
  52.     }  

封装的上传类库

[php] view plain copy

  1. <?php  
  2. /** 
  3.  * 
  4.  * 版权所有:重庆市环境保护信息中心 
  5.  * 作    者:Sqc 
  6.  * 日    期:2016-12-06 
  7.  * 版    本:1.0.0 
  8.  * 功能说明:用于视频等上传。 
  9.  * 
  10.  **/  
  11. namespace Org\Util;  
  12. Class Vupload  
  13. {     
  14.     //要配置的内容  
  15.     private $path = "./uploads";  
  16.     private $allowtype = array('jpg', 'gif', 'png', 'mp4', 'mp3','3gp','rmvb','mov','avi','m4v');  
  17.     private $maxsize = 104857600;//  
  18.     private $israndname = true;  
  19.   
  20.     private $originName;  
  21.     private $tmpFileName;  
  22.     private $fileType;  
  23.     private $fileSize;  
  24.     private $newFileName;  
  25.     private $errorNum = 0;  
  26.     private $errorMess = "";  
  27.       
  28.     private $isChunk = false;  
  29.     private $indexOfChunk = 0;  
  30.   
  31.     public function _initialize(){  
  32.         parent::_initialize();  
  33.     }  
  34.   
  35.     /** 
  36.      * 用于设置成员属性($path, $allowtype, $maxsize, $israndname) 
  37.      * 可以通过连贯操作一次设置多个属性值 
  38.      * @param $key  成员属性(不区分大小写) 
  39.      * @param $val  为成员属性设置的值 
  40.      * @return object 返回自己对象$this, 可以用于连贯操作 
  41.      */  
  42.     function set($key, $val){  
  43.         $key = strtolower($key);  
  44.         if (array_key_exists($key, get_class_vars(get_class($this)))){  
  45.             $this->setOption($key, $val);  
  46.         }  
  47.         return $this;  
  48.     }  
  49.   
  50.     /** 
  51.      * 调用该方法上传文件 
  52.      * Enter description here ... 
  53.      * @param $fileField    上传文件的表单名称 
  54.      * 
  55.      */  
  56.     function upload($fileField, $info){  
  57.       
  58.         //判断是否为分块上传  
  59.         $this->checkChunk($info);  
  60.           
  61.         if (!$this->checkFilePath($this->path)){  
  62.             $this->errorMess = $this->getError();  
  63.             return false;  
  64.         }  
  65.   
  66.         //将文件上传的信息取出赋给变量  
  67.         $name = $_FILES[$fileField]['name'];  
  68.         $tmp_name = $_FILES[$fileField]['tmp_name'];  
  69.         $size = $_FILES[$fileField]['size'];  
  70.         $error = $_FILES[$fileField]['error'];  
  71.   
  72.   
  73.         //设置文件信息  
  74.         if ($this->setFiles($name, $tmp_name, $size, $error)){  
  75.           
  76.             //如果是分块,则创建一个唯一名称的文件夹用来保存该文件的所有分块  
  77.             if($this->isChunk){  
  78.                 $uploadDir = $this->path;  
  79.                 if($info){  
  80.                     $tmpName = $this->setDirNameForChunks();  
  81.                      
  82.                      if(!$this->checkFilePath($uploadDir . '/' . $tmpName)){  
  83.                         $this->errorMess = $this->getError();  
  84.                         return false;  
  85.                     }  
  86.                 }  
  87.         //         $tmpName = $this->setDirNameForChunks($info);  
  88.         //         if(!$this->checkFilePath($uploadDir . '/' . $tmpName)){  
  89.                     // $this->errorMess = $this->getError();  
  90.         //          return false;  
  91.         //         }  
  92.                   
  93.                 //创建一个对应的文件,用来记录上传分块文件的修改时间,用于清理长期未完成的垃圾分块  
  94.                 touch($uploadDir.'/'.$tmpName.'.tmp');  
  95.             }  
  96.   
  97.             if($this->checkFileSize() && $this->checkFileType()){  
  98.                 $this->setNewFileName();  
  99.                 if ($this->copyFile()){  
  100.                     return $this->newFileName;  
  101.                 }  
  102.             }  
  103.         }  
  104.   
  105.         $this->errorMess = $this->getError();  
  106.         return false;  
  107.     }  
  108.   
  109.     public function chunksMerge($uniqueFileName, $chunksTotal, $fileExt){  
  110.         $targetDir = $this->path.'/'.$uniqueFileName;  
  111.         //检查对应文件夹中的分块文件数量是否和总数保持一致  
  112.         if($chunksTotal > 1 && (count(scandir($targetDir)) - 2) == $chunksTotal){  
  113.             //同步锁机制  
  114.             $lockFd = fopen($this->path.'/'.$uniqueFileName.'.lock', "w");  
  115.             if(!flock($lockFd, LOCK_EX | LOCK_NB)){  
  116.                 fclose($lockFd);  
  117.                 return false;  
  118.             }  
  119.   
  120.             //进行合并  
  121.             $this->fileType = $fileExt;  
  122.             $finalName = $this->path.'/'.($this->setOption('newFileName', $this->proRandName()));  
  123.             $file = fopen($finalName, 'wb');  
  124.             for($index = 0; $index < $chunksTotal; $index++){  
  125.                 $tmpFile = $targetDir.'/'.$index;  
  126.                 $chunkFile = fopen($tmpFile, 'rb');  
  127.                 $content = fread($chunkFile, filesize($tmpFile));  
  128.                 fclose($chunkFile);  
  129.                 fwrite($file, $content);  
  130.   
  131.                 //删除chunk文件  
  132.                 unlink($tmpFile);  
  133.             }  
  134.             fclose($file);  
  135.             //删除chunk文件夹  
  136.             rmdir($targetDir);  
  137.             unlink($this->path.'/'.$uniqueFileName.'.tmp');  
  138.   
  139.             //解锁  
  140.             flock($lockFd, LOCK_UN);  
  141.             fclose($lockFd);  
  142.             unlink($this->path.'/'.$uniqueFileName.'.lock');  
  143.   
  144.             return $this->newFileName;  
  145.   
  146.         }  
  147.         return false;  
  148.     }  
  149.   
  150.     //获取上传后的文件名称  
  151.     public function getFileName(){  
  152.         return $this->newFileName;  
  153.     }  
  154.   
  155.     //上传失败后,调用该方法则返回,上传出错信息  
  156.     public function getErrorMsg(){  
  157.         return $this->errorMess;  
  158.     }  
  159.   
  160.     //设置上传出错信息  
  161.     public function getError(){  
  162.         $str = "上传文件<font color='red'>{$this->originName}</font>时出错:";  
  163.         switch ($this->errorNum) {  
  164.             case 4:  
  165.                 $str.= "没有文件被上传";  
  166.                 break;  
  167.             case 3:  
  168.                 $str.= "文件只有部分被上传";  
  169.                 break;  
  170.             case 2:  
  171.                 $str.= "上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值";  
  172.                 break;  
  173.             case 1:  
  174.                 $str.= "上传的文件超过了php.ini中upload_max_filesize选项限制的值";  
  175.                 break;  
  176.             case -1:  
  177.                 $str.= "未允许的类型";  
  178.                 break;  
  179.             case -2:  
  180.                 $str.= "文件过大, 上传的文件夹不能超过{$this->maxsize}个字节";  
  181.                 break;  
  182.             case -3:  
  183.                 $str.= "上传失败";  
  184.                 break;  
  185.             case -4:  
  186.                 $str.= "建立存放上传文件目录失败,请重新指定上传目录";  
  187.                 break;  
  188.             case -5:  
  189.                 $str.= "必须指定上传文件的路径";  
  190.                 break;  
  191.   
  192.             default:  
  193.                 $str .= "未知错误";  
  194.         }  
  195.         return $str."<br>";  
  196.     }  
  197.   
  198.     //根据文件的相关信息为分块数据创建文件夹  
  199.     //md5(当前登录用户的数据库id + 文件原始名称 + 文件类型 + 文件最后修改时间 + 文件总大小)  
  200.     private function setDirNameForChunks(){  
  201.         $str = $_SESSION['userinfo']['openid'].$_SESSION['userinfo']['report_time'];  
  202.         return md5($str);  
  203.         return $str;   
  204.     }  
  205.   
  206.     //设置和$_FILES有关的内容  
  207.     private function setFiles($name="", $tmp_name="", $size=0, $error=0){  
  208.         $this->setOption('errorNum', $error);  
  209.         if ($error) {  
  210.             return false;  
  211.         }  
  212.         $this->setOption('originName', $name);  
  213.         $this->setOption('tmpFileName', $tmp_name);  
  214.         $aryStr = explode(".", $name);  
  215.         $this->setOption("fileType", strtolower($aryStr[count($aryStr)-1]));  
  216.         $this->setOption("fileSize", $size);  
  217.         return true;  
  218.     }  
  219.   
  220.     private function checkChunk($info){  
  221.         if(isset($info['chunks']) && $info['chunks'] > 0){  
  222.             $this->setOption("isChunk", true);  
  223.               
  224.             if(isset($info['chunk']) && $info['chunk'] >= 0){  
  225.                 $this->setOption("indexOfChunk", $info['chunk']);  
  226.                   
  227.                 return true;  
  228.             }  
  229.               
  230.             throw new Exception('分块索引不合法');  
  231.         }  
  232.           
  233.         return false;  
  234.     }  
  235.   
  236.     //为单个成员属性设置值  
  237.     private function setOption($key, $val){  
  238.         $this->$key = $val;  
  239.         return $val;  
  240.     }  
  241.   
  242.     //设置上传后的文件名称  
  243.     private function setNewFileName(){  
  244.         if($this->isChunk){     //如果是分块,则以分块的索引作为文件名称保存  
  245.             $this->setOption('newFileName', $this->indexOfChunk);  
  246.         }elseif($this->israndname) {  
  247.             $this->setOption('newFileName', $this->proRandName());  
  248.         }else{  
  249.             $this->setOption('newFileName', $this->originName);  
  250.         }  
  251.     }  
  252.   
  253.     //检查上传的文件是否是合法的类型  
  254.     private function checkFileType(){  
  255.         if (in_array(strtolower($this->fileType), $this->allowtype)) {  
  256.             return true;  
  257.         }else{  
  258.             $this->setOption('errorNum', -1);  
  259.             return false;  
  260.         }  
  261.     }  
  262.   
  263.   
  264.     //检查上传的文件是否是允许的大小  
  265.     private function checkFileSize(){  
  266.         if ($this->fileSize > $this->maxsize) {  
  267.             $this->setOption('errorNum', -5);  
  268.             return false;  
  269.         }else{  
  270.             return true;  
  271.         }  
  272.     }  
  273.   
  274.     //检查是否有存放上传文件的目录  
  275.     private function checkFilePath($target){  
  276.           
  277.         if (empty($target)) {  
  278.             $this->setOption('errorNum', -5);  
  279.             return false;  
  280.         }  
  281.           
  282.         if (!file_exists($target) || !is_writable($target)) {  
  283.             if (!@mkdir($target, 0755)) {  
  284.                 $this->setOption('errorNum', -4);  
  285.                 return false;  
  286.             }  
  287.         }  
  288.   
  289.         $this->path = $target;  
  290.         return true;  
  291.     }  
  292.   
  293.     //设置随机文件名  
  294.     private function proRandName(){  
  295.         $fileName = date('YmdHis')."_".rand(100,999);  
  296.         return $fileName.'.'.$this->fileType;  
  297.     }  
  298.   
  299.     //复制上传文件到指定的位置  
  300.     private function copyFile(){  
  301.         if (!$this->errorNum) {  
  302.             $path = rtrim($this->path, '/').'/';  
  303.             $path.= $this->newFileName;  
  304.             if (@move_uploaded_file($this->tmpFileName, $path)) {  
  305.                 return true;  
  306.             }else{  
  307.                 $this->setOption('errorNum', -3);  
  308.                 return false;  
  309.             }  
  310.         }else{  
  311.             return false;  
  312.         }  
  313.     }  
  314. }  

猜你喜欢

转载自blog.csdn.net/bl5t3z2x1/article/details/86686355