一个经典的PHP文件上传类
需求分析如下:
(1)支持单个文件上传
(2)支持多个文件上传
(3)可以指定保存位置 可以设置上传文件允许的大小和类型 可以选择重命名和保留原名
1 <!--
2 设计一个经典文件上传类
3 需求分析
4 (1)支持单个文件上传
5 (2)支持多个文件上传
6 (3)可以指定保存位置 可以设置上传文件允许的大小和类型 可以选择重命名和保留原名
7 程序设计
8 成员属性
9 成员方法
10
11 -->
12
13 <?php
14 error_reporting(E_ALL && !E_NOTICE);
15
16 class FileUpload{
17 private $path = "./uploads";
18 private $allowtype = array('jpg','gif','png','txt');
19 private $maxsize = 1000000;
20 private $israndname = true;//设置是否随机重命名文件
21
22 private $originName;
23 private $tmpFileName;
24 private $fileType;
25 private $fileSize;
26 private $newFileName;
27 private $errorNum = 0;
28 private $errorMess = "";
29
30 /**
31 * 用于设置成员属性
32 * 可以通过连贯操作设置多个值
33 */
34 function set($key,$val){
35 $key = strtolower($key);
36 if(array_key_exists($key,get_class_vars(get_class($this)))){
37 $this -> setOption($key,$val);
38 }
39 return $this;
40 }
41
42 /**
43 * 用该函数来上传文件
44 */
45 function upload($fileField){
46 $return = true;
47
48 //检查文件路径是否合法
49 if(!$this -> checkFilepath()){
50 $this -> errorMess = $this -> errorMess();
51 return false;
52 }
53 //将文件上传的信息取出赋值给变量
54 $name = $_FILES[$fileField]['name'];
55 $tmp_name = $_FILES[$fileField]['tmp_name'];
56 $size = $_FILES[$fileField]['size'];
57 $error = $_FILES[$fileField]['error'];
58
59 //如果是多个上传文件则$file['name']是数组
60 if(is_array($name)){
61 $errors = array();
62 //多个文件需要循环处理,此循环只有检查上传文件的作用,并没有真正上传
63 for($i = 0;$i < count($name);$i ++){
64 //设置文件信息
65 if($this -> setFiles($name[$i],$tmp_name[$i],$size[$i],$error[$i])){
66 if(!$this -> checkFileSize() || !$this -> checkFileType()){
67 $error[] = $this -> getError();
68 $return = false;
69 }
70 }else{
71 $errors[] = $this -> getError();
72 $return = false;
73 }
74 //如果有问题,则重新初始化属性
75 if(!$return)
76 $this -> setFiles();
77 }
78
79 if($return){
80 //存放所有上传文件名的变量数组
81 $fileNames = array();
82 //如果上传的多个文件都是合法的 则通过循环向服务器上传文件
83 for($i = 0;$i < count($name);$i ++){
84 if($this -> setFiles($name[$i],$tmp_name[$i],$size[$i],$error[$i])){
85 $this -> setNewfileName();
86 if(!$this -> copyFile()){
87 $errors[] = $this -> getError();
88 $return = false;
89 }
90 $filenames[] = $this -> newFileName;
91 }
92 }
93 $this -> newFileName = $fileNames;
94 }
95 $this -> errorMess = $errors;
96 return $return;
97 }else{
98 //设置文件信息
99 if($this -> setFiles($name,$tmp_name,$size,$error)){
100 //上传之前先判断一下大小和类型
101 if($this -> checkFileSize() && $this -> checkFileType()){
102 //为上传文件设置新名
103 $this -> setNewfileName();
104 //上传文件 成功返回true 失败返回false
105 if($this -> copyFile()){
106 return true;
107 }else{
108 $return = false;
109 }
110 }else{
111 $return = false;
112 }
113 }else{
114 $return = false;
115 }
116
117 //如果$return为false 则出错 将出错信息保存在属性errorMess中
118 if(!$return)
119 $this -> errorMess = $this -> getError();
120 return $return;
121 }
122 }
123
124 /**
125 * 获取上传后的文件名称
126 */
127 public function getFileName(){
128 return $this -> newFileName;
129 }
130
131 /**
132 * 上传失败后,调用该方法则调用该方法返回,上传出错信息
133 */
134 public function getErrorMsg(){
135 return $this -> errorMess;
136 }
137
138 //设置上传错误信息
139 private function getError(){
140 $str = "上传文件<font color = 'red'>{$this -> originName}</font>时出错 :";
141 switch($this -> errorNum){
142 case 4:$str .= "没有文件被上传";break;
143 case 3:$str .= "文件只有部分被上传";break;
144 case 2:$str .= "上传文件的大小超过了HTML表单中指定的值";break;
145 case 1:$str .= "上传文件的大小超过了php.ini中指定的值";break;
146 case -1:$str .= "未允许类型";break;
147 case -2:$str .= "文件过大,上传的文件不能超过{$this -> maxsize}个字节";break;
148 case -3:$str .= "上传失败";break;
149 case -4:$str .= "建立存放上传文件目录失败,请重新指定上传目录";break;
150 case -5:$str .= "必须指定上传文件的路径";break;
151 default:$str .= "未知错误";
152 }
153 return $str.'<br>';
154 }
155
156 //设置和$_FILES有关的内容
157 private function setFiles($name = "",$tmp_name = "",$size = "",$error = 0){
158 $this -> setOption('errorNum',$error);
159 if($error)
160 return false;
161 $this -> setOption('originName',$name);
162 $this -> setOption('tmpFileName',$tmp_name);
163 $aryStr = explode(".",$name);
164 $this -> setOption('fileType',strtolower($aryStr[count($aryStr) - 1]));
165 $this -> setOption('fileSize',$size);
166 return true;
167 }
168
169 //为单个成员属性设置值
170 private function setOption($key,$val){
171 $this -> $key = $val;
172 }
173
174 //设置上传后的文件名称
175 private function setNewfileName(){
176 if($this -> israndname){
177 $this -> setOption('newFileName',$this -> proRandName());
178 }else{
179 $this -> setOption('newFileName',$this -> originName);
180 }
181 }
182
183 //检查上传文件是否是合法的类型
184 private function checkFileType(){
185 if(in_array(strtolower($this -> fileType),$this -> allowtype)){
186 return true;
187 }else{
188 $this -> setOption('errorNum',-1);
189 return false;
190 }
191 }
192
193 //检查上传文件是否是允许的大小
194 private function checkFileSize(){
195 if($this -> fileSize > $this -> maxsize){
196 $this -> setOption('errorNum',-2);
197 return false;
198 }else{
199 return true;
200 }
201 }
202
203 //检查是否有存放上传文件的目录
204 private function checkFilepath(){
205 if(empty($this -> path)){
206 $this -> setOption('errorNum',-5);
207 return false;
208 }
209 if(!file_exists($this -> path) || !is_writable($this -> path)){
210 if(!@mkdir($this -> path)){
211 $this -> setOption('errorNum',-4);
212 return false;
213 }
214 }
215 return true;
216 }
217
218 //设置随机文件名
219 private function proRandName(){
220 $filename = date('YmdHis')."_".rand(100,999);
221 return $filename.".".$this -> fileType;
222 }
223
224 //复制上传文件到指定位置
225 private function copyFile(){
226 if(!$this -> errorNum){
227 $path = rtrim($this -> path,'/').'/';
228 $path .= $this -> newFileName;
229 if(@move_uploaded_file($this -> tmpFileName,$path)){
230 return true;
231 }else{
232 $this -> setOption('errorNum',-3);
233 return false;
234 }
235 }else{
236 return false;
237 }
238 }
239
240
241
242
243 }
244 ?>
上面为一个文件上传类 想要用到这个类需要另写一个PHP文件来调用该类
内容如下
1 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 2 3 <?php 4 /** 5 使用文件上传类fileupload.class.php 处理单个或多个文件上传 6 */ 7 8 error_reporting(E_ALL && !E_NOTICE); 9 require "fileupload.class.php";//将文件上传类的文件包含进来 10 11 $up = new FileUpload; 12 13 //可以通过set方法设置上传的属性 设置多个属性set方法可以单独调用 也可以连贯操作一起调用多个 14 /* $up -> set('path','./newpath/') 15 -> set('size',1000000) 16 -> set('allowtype',array('gif','png','jpg','txt')) 17 -> set('israndname',false); 18 */ 19 //调用$up对象的upload方法上传文件 myfile是表单的名称 上传成功返回true 否则返回false 20 if($up -> upload('myFile')){ 21 //如果是多个文件 返回数组 存放所有上传后的文件名 单文件上传则直接返回文件名称 22 print_r($up -> getFileName()); 23 }else{ 24 //如果是多个文件 返回数组 多条出错信息 单文件上传则直接返回一条错误报告 25 print_r($up -> getErrorMsg()); 26 } 27 ?>
然后在写一个HTML文件作为前端 使用上面运用到文件上传类的文件
单文件上传:
1 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 2 <html> 3 <head><title>单个文件上传</title></head> 4 5 <body> 6 <form action = "upload.php" method = "POST" enctype = "multipart/form-data"> 7 <input type = "hidden" name = "MAXN_FILIE_SIZE" value = "100000"> 8 选择文件:<input type = "file" name = "myFile"> 9 <input type = "submit" value = "上传文件"> 10 </form> 11 </body> 12 </html>
多文件上传:
1 <meta http-equiv="Content-Type" content="text/html;charset=utf-8"> 2 <html> 3 <head><title>单个文件上传</title></head> 4 5 <body> 6 <form action = "upload.php" method = "POST" enctype = "multipart/form-data"> 7 <input type = "hidden" name = "MAXN_FILIE_SIZE" value = "100000"> 8 选择文件1:<input type = "file" name = "myFile[]"> 9 选择文件2:<input type = "file" name = "myFile[]"> 10 选择文件3:<input type = "file" name = "myFile[]"> 11 <input type = "submit" value = "上传文件"> 12 </form> 13 14 </body> 15 </html>