PHP文件上传类

  1 class FileUpload {
  2  /**
  3    * 文件上传类
  4    * @author lhm
  5    * for example
  6    * $up=new FileUpload(array('israndname'=>true,
  7    *                           'allowType'=>array('txt', 'doc', 'php', 'gif','jpg'),
  8    *                           'filepath'=>'./uploads/', 
  9    *                           'maxSize'=>2000000));
 10    * $up->uploadFile('pic');//pic 为文件输入框name值
 11    */
 12     private $filepath;     //指定上传文件保存的路径
 13     private $allowtype=array('gif', 'jpg', 'png', 'jpeg');  //充许上传文件的类型
 14     private $maxsize=2000000;  //允上传文件的最大长度 2M
 15     private $israndname=true;  //是否随机重命名, true false不随机,使用原文件名
 16     private $originName;   //源文件名称
 17     private $tmpFileName;   //临时文件名
 18     private $fileType;  //文件类型
 19     private $fileSize;  //文件大小
 20     private $newFileName; //新文件名
 21     private $errorNum=0;  //错误号
 22     private $errorMess=''; //用来提供错误报告
 23 
 24     
 25     /**
 26      * 用于上传文件初始化
 27      * 用户可以不用按位置传参数,后面参数给值不用将前几个参数也提供值
 28      */
 29     function __construct($options = array()){
 30         $allowOption = array('filepath','allowtype','maxsize','israndname');
 31         foreach($options as $key=>$val){
 32             $key = strtolower($key);
 33             //查看用户参数中数组的下标是否和成员属性名相同
 34             //if(!in_array($key,get_class_vars(get_class($this)))){
 35             if(!in_array($key, $allowOption)){
 36                 $this->setOption('errorNum', 5);
 37                 $this->errorMess = $this->getError();
 38                 continue 1;
 39             }
 40             $this->setOption($key, $val);
 41         }
 42     }
 43     
 44     /**
 45      * 
 46      * 用来检查文件上传路径
 47      * @access private
 48      * @return bool
 49      */
 50     private function checkFilePath(){
 51         if(empty($this->filepath)) {
 52             $this->setOption('errorNum', -5);
 53             return false;
 54         }
 55 
 56         if(!file_exists($this->filepath) || !is_writable($this->filepath)){
 57             if(!@mkdir($this->filepath, 0755)){
 58                 $this->setOption('errorNum', -4);
 59                 return false;
 60             }
 61         }
 62         return true;
 63     }
 64     /**
 65      * 
 66      * 用来检查文件上传的大小
 67      * @access private
 68      * @return bool
 69      */
 70     private function checkFileSize() {
 71         if($this->fileSize > $this->maxsize){
 72             $this->setOPtion('errorNum', -2);
 73             return false;
 74         }else{
 75             return true;
 76         }
 77     }
 78     /**
 79      * 
 80      * 用于检查文件上传类型
 81      * @access private
 82      * @return bool
 83      */
 84     private function checkFileType() {
 85         if(in_array(strtolower($this->fileType), $this->allowtype)) {
 86             return true;
 87         }else{
 88             $this->setOption('errorNum', -1);
 89             return false;
 90         }
 91     }
 92     /**
 93      * 
 94      * 检查文件真实上传数量,如果文件名为空,则删除对应元素值
 95      * @access private
 96      * @param array $name
 97      * @param array $tmpName
 98      * @param array $size
 99      * @param array $error
100      * @param array $fileField
101      */
102     private function checkFileNum($name, $tmpName, $size, $error, $fileField){
103         $continue = true;
104         for($i=0; $i < count($name); $i++){
105             if ($name[$i] === ''){
106                 $name = $this->deleteArrayElement($name, $i);//线性删除
107                 $tmpName = $this->deleteArrayElement($tmpName, $i);
108                 $size = $this->deleteArrayElement($size, $i);
109                 $error = $this->deleteArrayElement($error, $i);
110                 $continue = false;
111                 break 1;
112             }
113         }
114         if ($continue === false){
115             $this->checkFileNum($name, $tmpName, $size, $error, $fileField);//递归
116         }else {
117             //将空空元素删除后重新赋给$_FILES
118             $_FILES[$fileField]['name'] = $name;
119             $_FILES[$fileField]['tmp_name'] = $tmpName;
120             $_FILES[$fileField]['size'] = $size;
121             $_FILES[$fileField]['error'] = $error;
122         }
123         
124     }
125     /**
126      * 
127      * 设置上传后的文件名称
128      * @access private
129      */
130     private function setNewFileName(){
131         if($this->israndname){
132             $this->setOption('newFileName', $this->setRandName());//系统随机名
133         } else {
134             $this->setOption('newFileName', $this->originName);//沿用文件旧名
135         }
136     }
137     /**
138      * 
139      * 设置随机文件名称
140      * @access private
141      * @return string
142      */
143     private function setRandName(){
144         $fileName = date("YmdHis").rand(100,999);
145         return $fileName.'.'.$this->fileType;
146     }
147     /**
148      * 
149      * 自动生成属性并赋值
150      * @param string $key
151      * @param string $val
152      */
153     private function setOption($key, $val){
154         $this->$key=$val;
155     }
156     /**
157      * 
158      * 用于上传文件
159      * @param string $fileField
160      */
161     public function uploadFile($fileField){
162         $return=true;
163         //检查初始化是否出错
164         if ($this->errorNum != 0){
165             $this->errorMess = $this->getError();
166             return false;
167         }
168         //检查文件上传路径
169         if(!$this->checkFilePath()){
170             $this->errorMess = $this->getError();
171             return false;
172         }
173 
174         $this->checkFileNum($_FILES[$fileField]['name'],$_FILES[$fileField]['tmp_name'],
175                             $_FILES[$fileField]['size'],$_FILES[$fileField]['error'],
176                             $fileField);
177         $name = $_FILES[$fileField]['name'];
178         $tmpName = $_FILES[$fileField]['tmp_name'];
179         $size = $_FILES[$fileField]['size'];
180         $error = $_FILES[$fileField]['error'];
181         //print_r($name);
182         if(is_Array($name)){
183             $errors = array();
184             $count = count($name);
185             for($i=0; $i < $count; $i++){
186                 if($this->setFiles($name[$i], $tmpName[$i], $size[$i], $error[$i])){
187                     if(!$this->checkFileSize() || !$this->checkFileType()){
188                         $errors[] = $this->getError();
189                         $return=false;
190                     }
191                 }else{
192                     $error[] = $this->getError();
193                     $return = false;
194                 }
195 
196                 if(!$return)
197                     $this->setFiles();
198             }
199 
200             if($return){
201                 $fileNames = array();
202                 for($i = 0; $i < $count; $i++){
203                     if($this->setFiles($name[$i], $tmpName[$i], $size[$i], $error[$i])){
204                         $this->setNewFileName();
205                         if(!$this->copyFile()){
206                             $errors = $this->getError();
207                             $return = false;
208                         }else{
209                             $fileNames[] = $this->newFileName;
210                         }
211                     }
212                 }
213 
214                 $this->newFileName = $fileNames;
215             }
216             $this->errorMess = $errors;
217         }else{
218             if($this->setFiles($name, $tmpName, $size, $error)){
219                 if($this->checkFileSize() && $this->checkFileType()){
220                     $this->setNewFileName();
221 
222                     if($this->copyFile()){
223                         return true;
224                     }else{
225                         $return = false;
226                     }
227                         
228                 }else{
229                     $return = false;
230                 }    
231             }else{
232                 $return = false;
233             }
234 
235             if(!$return)
236                 $this->errorMess = $this->getError();    
237         }    
238         return $return;        
239     }
240     /**
241      * 
242      * 将临时文件移动到正式路径
243      * @access private
244      * @return bool
245      */
246     private function copyFile(){
247         if(!$this->errorNum){
248             $filepath = rtrim($this->filepath, '/').'/';
249             $filepath .= $this->newFileName;
250 
251             if(@move_uploaded_file($this->tmpFileName, $filepath))    {
252                 return true;
253             }else{
254                 $this->setOption('errorNum', -3);
255                 return false;
256             }
257                 
258         }else{
259             return false;
260         }
261     }
262     /**
263      * 设置文件属性的值
264      */
265     private function setFiles($name = '', $tmpName = '', $size = 0, $error = 0){
266     
267         $this->setOption('errorNum', $error);
268             
269         if($error){
270             return false;
271         }
272 
273         $this->setOption('originName', $name);
274         $this->setOption('tmpFileName', $tmpName);
275         $arrStr=explode('.', $name); 
276         $this->setOption('fileType', strtolower($arrStr[count($arrStr)-1]));
277         $this->setOption('fileSize', $size);    
278 
279         return true;
280     }
281     /**
282      * 
283      * 线性删除
284      * @access private
285      * @param array $array
286      * @param int $i
287      * @return array;
288      */    
289     private function deleteArrayElement($array , $i) { 
290         $count = count($array);  
291         for ($j = $i; $j < $count; $j ++){ 
292                 $array[$j] = $array [$j+1]; 
293         } 
294         array_pop ($array); 
295         return $array ; 
296     }
297     /**
298      * 
299      * 用于获取上传后文件的文件名
300      * @access public
301      * @return string
302      */
303     public function getNewFileName(){
304         return $this->newFileName;
305     }
306     /**
307      * 
308      * 获取上传错误信息
309      * @access private
310      * @return string
311      */
312     private function getError(){
313         $str='上传文件<font color="red">'.$this->originName.'</font>时出错:';
314 
315         switch($this->errorNum){
316             case 5: $str .= '初始化参数出错';
317                 break;
318             case 4: $str .= '没有文件被上传'; 
319                 break;
320             case 3: $str .= '文件只被部分上传'; 
321                 break;
322             case 2: $str .= '上传文件超过了HTML表单中MAX_FILE_SIZE选项指定的值';
323                 break;
324             case 1: $str .= '上传文件超过了php.ini 中upload_max_filesize选项的值';
325                 break;
326             case -1: $str .= '末充许的类型';
327                 break;
328             case -2: $str .= '文件过大,上传文件不能超过'.$this->maxSize.'个字节';
329                 break;
330             case -3: $str .= '上传失败';
331                 break;
332             case -4: $str .= '建立存放上传文件目录失败,请重新指定上传目录';
333                 break;
334             case -5: $str .= '必须指定上传文件的路径';
335                 break;
336             default: $str .= '末知错误';
337         }
338 
339         return $str.'<br>';
340     }
341     /**
342      * 
343      * 查看错误报告
344      * @access public
345      * @return string
346      */
347     public function getErrorMsg() {
348         return $this->errorMess;
349     }
350 }

 

posted @ 2014-01-15 14:17  标签  阅读(326)  评论(0编辑  收藏  举报