PHP文件上传处理

web中,文件上传是一个很常用的功能。如:上传头像、上传图片。这些提交到后台的图片都要交给后端处理。php提供了几个上传处理的函数,我把它们封装成类,以便日后使用。
处理流程(可能有不合理的地方,用时再做简单的修改):
1. 检查是否是合法的上传文件;
2. 检查是否上传成功;
3. 检查文件大小;
4. 验证文件后缀;
5. 移动文件长久保存;
以下是类的具体代码:

<?php
//处理上传的文件
class uploadFile{
    public $filename; //上传时设置表单中的文件名
    public $fileInfo; //上传的文件的信息
    public $maxSize=50000; //允许的最大文件大小(字节)
    public $fileSuffex='txt|zip||';//允许的文件后缀,例如:*(任意) 或者 txt|zip|| 格式,表示后缀名可以是txt、zip或者没有
    public $fileDir='/home/WWW/tmp/';//设置指定目录
    public $newFileName; //设置新文件名字

    private $filePath;//最终文件的路径与文件名,$fileDir.$newFileName

    public function __construct($filename=null,$newFile='ulfile'){
    $this->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文件:

<!DOCTYPE html>
<html>
    <head>
        <title>TODO supply a title</title>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
    </head>
    <body>
        <h1>上传文件</h1>
        <form method="POST" action="acceptFile.php" enctype="multipart/form-data">
            <input type="hidden" name="MAX_FILE_SIZE" value="1000000"/>
            请选择文件:<input type="file" name="ulFile"/>
            <button>上传</button>
        </form>
    </body>
</html>

提交到acceptFile.php(与uploadFile.php在同一文件夹):

<?php

//导入上传文件处理类
define('THISDIR',dirname(__FILE__).'/');
require_once(THISDIR.'uploadFile.php');

$ulFile=new uploadFile('ulFile','newFile');
$state=$ulFile->handle();
if($state==1){
    echo '文件上传并处理成功!';
}else{
    echo '文件上传或处理时出错,错误代码:'.$state;
}

var_dump($ulFile->fileInfo);

注意:脚本开头定义了一个常量’THISDIR’,从名字就可以看出它的内容是当前的文件夹路径,这是为了使用绝对路径来require处理类,以免出现路径问题而引用失败。(关于这个内容参见:PHP中require和include路径问题详解

然后开启web服务器,访问upload.html,选择文件并上传:
点击浏览,选择要上传的文件
这个文件并没有后缀,所以后缀就为空。
点击上传
结果:
上传成功

试着传个带扩展名的:
有扩展名的文件
结果:
上传失败
可以看到,有错误代码返回,所以失败了。大家可以查看类里面的错误代码看到对应的错误是后缀验证失败。因为我们设置的后缀里没有conf。而第一次上传的文件中的后缀为空,在我们设置的后缀中是包含没有后缀的文件的!当然,设置为 * 就不限制后缀了。

最后一个问题,虽然上传失败了,但是文件还是传到服务器的临时文件夹了,因为系统判断的上传并没有问题。所以,要定期清理一下服务器的临时文件夹,有的系统可能会定时清空临时目录。最好的方法是写个脚本定时清理,或者再写个删除上传失败的临时文件的方法。

 

posted @ 2016-04-01 18:09  新月的力量_141  阅读(234)  评论(0编辑  收藏  举报