为了账号安全,请及时绑定邮箱和手机立即绑定

单文件上传(未精简)

<?php
class FileUpload{
    private $datainfo;//上传文件的数据信息
    private $allow_size;//允许上传文件的大小
    private $allow_type;//允许类型数组
    private $temp_fileExt;//上传文件扩展名
    private $file_category;//上传文件的种类

    private $rootPath;//存放的根路径
    private $destination;//文件最终存放的全路径
    
    public function __construct($name,$allow_size,$allow_type,$rootPath="./upload/"){
        //检测服务器$_FILES中是否有上传数据
        if(!$this->is_uploadfile_exists($name)){
            exit("客户端文件未上传至服务端,请检查表单提交方式是否为post并且encotype的字符串是否正确,还有input的name名字是否正确等phpini的配置!");
        }
        $this->init($name,$allow_size,$allow_type,$rootPath);
        //检查临时文件是否是通过Post方式上传的
        if(!$this->is_httpPost_upload()){
            exit("上传的文件不是通过Http的Post方式上传的,Game Over!");
        }
        //检查客户端上传文件至服务端是否有错误
        if($this->checkError()){
            $this->showErrorMessage();
        }
        //检查上传的文件大小
        if($this->checkSize()){
            exit("上传文件失败! 上传文件大小超出允许范围");
        }
        $this->setTempFileExt();
        //检查上传的文件类型是否符合要求
        if(!$this->checkFileType()){
            exit("上传文件失败! 文件类型不符合");
        }
        //如果文件是图片类型,检测其是不是真实的图片
        if($this->file_category=="image"){
            $result=$this->is_realPic();
            if($result===false){
                exit("上传文件失败! 该文件不是一个真实的图片文件,Game Over");
            }
        }
        //移动文件参数初始化
        $this->move_params_init();

    }

    public function file_move(){
        //移动文件是否成功
        $result=move_uploaded_file($this->datainfo["tmp_name"],$this->destination);
        if($result===false){
            exit("文件上传失败!在移动临时文件至最终目录下失败");
        }
        else{
            echo "文件上传成功!";
        }
    }

    /*
    *    @function 检测文件是否由客户端上传至服务端
    *    @return boolean 返回true表示已经上传到了,false表示没有上传到
    */
    public function is_uploadfile_exists($name){
        if(isset($_FILES[$name])){
            return true;
        }
        else{
            return false;
        }
    }
    
    /*
    *    @function 初始化上传文件参数 
    */
    public function init($name,$allow_size,$allow_type,$rootPath){
        $this->datainfo=$_FILES[$name];
        $this->allow_size=$allow_size;
        $this->allow_type=$allow_type;
        $this->rootPath=$rootPath;
    }
    
    /*
    *    @function 是否httpPost方式上传的
    *    @return boolean 返回true表示是,false表示否
    */
    public function is_httpPost_upload(){
        if(is_uploaded_file($this->datainfo["tmp_name"])){
            return true;
        }
        else{
            return false;
        }
    }
    
    /*
    *    @function 上传是否有错
    *    @return boolean 返回true表示有错误,false表示无错误
    */
    public function checkError(){
        if($this->datainfo["error"]==0){
            return false;
        }
        else{
            return true;
        }
    }
    
    /*
    *    @function 显示错误信息并退出
    *    @return none
    */
    public function showErrorMessageExit(){
        $err=$this->datainfo["error"];
        $errMessage="";
        switch($err){
            case 1:
                $errMessage="上传的文件超过了php.ini中upload_max_filesize选项限制的值";
                break;
            case 2:
                $errMessage="上传文件的大小超过了HTML表单中MAX_FILE_SIZE选项指定的值";
                break;
            case 3:
                $errMessage="文件只有部分被上传";
                break;
            case 4:
                $errMessage="没有文件被上传";
                break;
            case 6:
                $errMessage="找不到临时文件夹";
                break;
            case 7:
                $errMessage="文件写入失败";
                break;
            default:
                $errMessage="系统错误";
                break;
        }
        exit("文件上传失败! ".$errMessage);
    }
    
    /*
    *    @function 文件大小是否超出允许值
    *    @return boolean 返回true表示超过允许大小,false表示没有超出允许大小
    */
    public function checkSize(){
        if($this->allow_size<$this->datainfo["size"]){
            return true;
        }
        else{
            return false;
        }
    }

    /*
    *    @function 设定服务器临时文件的真正文件类型
    */
    public function setTempFileExt(){
        /* 最笨的办法,遇到串改type就彻底完蛋
        $this->temp_fileExt=$this->datainfo["type"];
        */
        //粗糙的处理方式,遇到xx.xx.jpg等特殊命名的文件名就直接完蛋
        $this->temp_fileExt=pathinfo($this->datainfo["name"],PATHINFO_EXTENSION);
        
        /* 因为php版本低于5.3 finfo_open无法使用
        $ext=$this->getFileExt();
        $this->temp_fileExt=$ext;
        */
    }    
    
    /*
    *    @function 获取文件后类型名
    *    @param none
    *    @return string文件类型名
    *    @notice 先通过内部匹配获得文件类型,如果无法匹配就只能截取出头文件转十六进制进行类型码匹配了
    */
    public function getFileExt(){
        $file=$this->datainfo["tmp_name"];
        $finfo=finfo_open(FILEINFO_MIME);//finfo过程化的使用return a mini type且只有在php5.3以上
        if(!finfo){
            //针对获取不到mini type的情况的补救,打开文件截取4个字节
            $res=fopen($file,"rb");
            $bin=fread($res,4);
            fclose($res);
            $arr=unpack("c4chars",$bin);
            //dechex() 函数把十进制转换为十六进制
            $code=dechex($arr["chars1"]).dechex($arr["chars2"]).dechex($arr["chars3"]).dechex($arr["chars4"]);//组成16进制数
            $ext=$this->getFileTypeByC4chars_TypeCode($code);//根据类型码查找硬编码值查表
        }
        else{
            $ext=finfo_file(finfo,$file);
        }
        finfo_close($finfo);//关闭资源
        return $ext;
    }
    //太长了发布不了接下面

正在回答

1 回答

举报

0/150
提交
取消
PHP实现文件上传与下载
  • 参与学习       43735    人
  • 解答问题       328    个

本课程讲解了文件上传的原理和配置,学会两种方式实现文件上传与下载

进入课程

单文件上传(未精简)

我要回答 关注问题
意见反馈 帮助中心 APP下载
官方微信