web中,文件上传是一个很常用的功能。如:上传头像、上传图片。这些提交到后台的图片都要交给后端处理。php提供了几个上传处理的函数,我把它们封装成类,以便日后使用。
处理流程(可能有不合理的地方,用时再做简单的修改): 1. 检查是否是合法的上传文件; 2. 检查是否上传成功; 3. 检查文件大小; 4. 验证文件后缀; 5. 移动文件长久保存; 以下是类的具体代码:filename=$filename; $this->newFileName=$newFile; $this->fileInfo=&$_FILES[$filename]; $this->filePath=$this->fileDir.$newFile; } /** * 处理整个上传流程,成功则返回1,失败返回相应的错误代码 * @return int */ public function handle(){ if($this->filename){ if(!$this->isUpload()) return 2;//非上传文件 if(!$this->successed()) return 3;//上传失败 if(!$this->checkSuffex()) return 4;//指定后缀无效 if(!$this->checkSize()) return 5;//上传文件太大 if(!$this->moveFile()) return 6;//移动文件失败 return 1;//文件上传并处理成功 }else return 0;//未设置上传时指定的文件名 } /** * 检查是否是上传文件 * @return boolean */ private function isUpload(){ if(is_uploaded_file($this->fileInfo['tmp_name'])) return true; else return false; } /** * 检查是否上传成功,成功返回true,失败返回false * @return boolean */ public function successed(){ if($this->filename){ $state=$this->fileInfo['error']; if($state==0) return true; else return false; } } /** * 判断文件后缀是否在指定列表中 * @return boolean */ private function checkSuffex(){ if($this->fileSuffex=='*') return true;// $tempNames=explode('.',$this->fileInfo['name']);//不能直接使用函数的返回创建引用// $currentSuffex=end($tempNames);//end()需要传入引用 // var_dump($currentSuffex); $currentSuffex= pathinfo($this->fileInfo['name'],PATHINFO_EXTENSION); $suffexArray= explode('|', $this->fileSuffex); if(in_array($currentSuffex, $suffexArray)){ return true; }else return false; } /** * 检查上传的文件的大小是否指定限制 * @return boolean */ private function checkSize(){ if($this->fileInfo['name']<=$this->maxSize) return true; else return false; } /** * 移动文件到指定目录,返回boolean * @return boolean */ private function moveFile(){ if(move_uploaded_file($this->fileInfo['tmp_name'], $this->filePath)) return true; else return false; }}
接下来测试一下,新建一个html文件:
TODO supply a title 上传文件
提交到acceptFile.php(与uploadFile.php在同一文件夹):
handle();if($state==1){ echo '文件上传并处理成功!';}else{ echo '文件上传或处理时出错,错误代码:'.$state;}var_dump($ulFile->fileInfo);
注意:脚本开头定义了一个常量’THISDIR’,从名字就可以看出它的内容是当前的文件夹路径,这是为了使用绝对路径来require处理类,以免出现路径问题而引用失败。(关于这个内容参见:)
然后开启web服务器,访问upload.html,选择文件并上传:
这个文件并没有后缀,所以后缀就为空。 结果:试着传个带扩展名的:
结果: 可以看到,有错误代码返回,所以失败了。大家可以查看类里面的错误代码看到对应的错误是后缀验证失败。因为我们设置的后缀里没有conf。而第一次上传的文件中的后缀为空,在我们设置的后缀中是包含没有后缀的文件的!当然,设置为 * 就不限制后缀了。最后一个问题,虽然上传失败了,但是文件还是传到服务器的临时文件夹了,因为系统判断的上传并没有问题。所以,要定期清理一下服务器的临时文件夹,有的系统可能会定时清空临时目录。最好的方法是写个脚本定时清理,或者再写个删除上传失败的临时文件的方法。