0

我的帖子

个人中心

设置

  发新话题
看了十来个别人写好的文件上传类,结合自己前段时间学习的设计模式,觉得这些类代码还有改进的空间哈。但自己时间有限,仅分享下别人的代码,然后提一下哪些地方值得改进就行了哈!以后有时间再说具体实现啦。
文件上传类代码,无非就是检查文件属性是否符合设计者要求,然后批量上传、保存、记录到数据库,还有的会生成缩略图……
我仅提出两点可能需要改进的地方:
1.尽量不用@,改用try{...}catch{...},也许更严谨些;
2.在105行附近的判断if(is_Array($name)),其实可以合并这个if...else...的,办法就是:如果$name不是数组,就把它赋值给数组,这样就可以直接用数组的方式运行了,而不用单独以单个文件方式再次编一次码。
<?php
class FileUpload {
    private $filepath; //指定上传文件保存的路径
    private $allowtype=array('gif', 'jpg', 'png', 'jpeg'); //充许上传文件的类型
    private $maxsize=1000000; //允上传文件的最大长度 1M
    private $israndname=true; //是否随机重命名, false不随机,使用原文件名
    private $originName; //源文件名称
    private $tmpFileName; //临时文件名
    private $fileType; //文件类型
    private $fileSize; //文件大小
    private $newFileName; //新文件名
    private $errorNum=0; //错误号
    private $errorMess=""; //用来提供错误报告

//用于对上传文件初使化
//1. 指定上传路径, 2,充许的类型, 3,限制大小, 4,是否使用随机文件名称
//让用户可以不用按位置传参数,后面参数给值不用将前几个参数也提供值
    function __construct($options=array()){
        foreach($options as $key=>$val){
            $key=strtolower($key);
//查看用户参数中数组的下标是否和成员属性名相同
            if(!in_array($key,get_class_vars(get_class($this)))){
                continue;
            }
            $this->setOption($key, $val);
        }
    }
    private function getError(){
        $str="上传文件<font color='red'>{$this->originName}</font>时出错:";
        switch($this->errorNum){
            case 4: $str .= "没有文件被上传"; break;
            case 3: $str .= "文件只被部分上传"; break;
            case 2: $str .= "上传文件超过了HTML表单中MAX_FILE_SIZE选项指定的值"; break;
            case 1: $str .= "上传文件超过了php.ini 中upload_max_filesize选项的值"; break;
            case -1: $str .= "末充许的类型"; break;
            case -2: $str .= "文件过大,上传文件不能超过{$this->maxSize}个字节"; break;
            case -3: $str .= "上传失败"; break;
            case -4: $str .= "建立存放上传文件目录失败,请重新指定上传目录"; break;
            case -5: $str .= "必须指定上传文件的路径"; break;
            default: $str .= "末知错误";
        }
        return $str.'<br>';
    }
//用来检查文件上传路径
    private function checkFilePath(){
        if(empty($this->filepath)) {
            $this->setOption('errorNum', -5);
            return false;
        }
        if(!file_exists($this->filepath) || !is_writable($this->filepath)){
            if(!@mkdir($this->filepath, 0755)){
                $this->setOption('errorNum', -4);
                return false;
            }
        }
        return true;
    }
//用来检查文件上传的大小
    private function checkFileSize() {
        if($this->fileSize > $this->maxsize){
            $this->setOPtion('errorNum', '-2');
            return false;
        }else{
            return true;
        }
    }
//用于检查文件上传类型
    private function checkFileType() {
        if(in_array(strtolower($this->fileType), $this->allowtype)) {
            return true;
        }else{
            $this->setOption('errorNum', -1);
            return false;
        }
    }
//设置上传后的文件名称
    private function setNewFileName(){
        if($this->israndname){
            $this->setOption('newFileName', $this->proRandName());
        } else {
            $this->setOption('newFileName', $this->originName);
        }
    }

//设置随机文件名称
    private function proRandName(){
        $fileName=date("YmdHis").rand(100,999);
        return $fileName.'.'.$this->fileType;
    }
    private function setOption($key, $val){
        $this->$key=$val;
    }
//用来上传一个文件
    function uploadFile($fileField){
        $return=true;
//检查文件上传路径
        if(!$this->checkFilePath()){
            $this->errorMess=$this->getError();
            return false;
        }
        $name=$_FILES[$fileField]['name'];
        $tmp_name=$_FILES[$fileField]['tmp_name'];
        $size=$_FILES[$fileField]['size'];
        $error=$_FILES[$fileField]['error'];
        if(is_Array($name)){
            $errors=array();
            for($i=0; $i<count($name); $i++){
                if($this->setFiles($name[$i], $tmp_name[$i], $size[$i], $error[$i])){
                    if(!$this->checkFileSize() || !$this->checkFileType()){
                        $errors[]=$this->getError();
                        $return=false;
                    }
                }else{
                    $error[]=$this->getError();
                    $return=false;
                }
                if(!$return)
                    $this->setFiles();
            }
            if($return){
                $fileNames=array();
                for($i=0; $i<count($name); $i++){
                    if($this->setFiles($name[$i], $tmp_name[$i], $size[$i], $error[$i])){
                        $this->setNewFileName();
                        if(!$this->copyFile()){
                            $errors=$this->getError();
                            $return=false;
                        }else{
                            $fileNames[]=$this->newFileName;
                        }
                    }
                }
                $this->newFileName=$fileNames;
            }
            $this->errorMess=$errors;
            return $return;
        } else {
            if($this->setFiles($name, $tmp_name, $size, $error)){
                if($this->checkFileSize() && $this->checkFileType()){
                    $this->setNewFileName();
                    if($this->copyFile()){
                        return true;
                    }else{
                        $return=false;
                    }
                }else{
                    $return=false;
                }
            }else{
                $return=false;
            }
            if(!$return)
                $this->errorMess=$this->getError();
            return $return;
        }
    }
    private function copyFile(){
        if(!$this->errorNum){
            $filepath=rtrim($this->filepath, '/').'/';
            $filepath.=$this->newFileName;
            if(@move_uploaded_file($this->tmpFileName, $filepath)) {
                return true;
            }else{
                $this->setOption('errorNum', -3);
                return false;
            }
        }else{
            return false;
        }
    }
//设置和$_FILES有关的内容
    private function setFiles($name="", $tmp_name='', $size=0, $error=0){
        $this->setOption('errorNum', $error);
        if($error){
            return false;
        }
        $this->setOption('originName', $name);
        $this->setOption('tmpFileName', $tmp_name);
        $arrStr=explode('.', $name);
        $this->setOption('fileType', strtolower($arrStr[count($arrStr)-1]));
        $this->setOption('fileSize', $size);
        return true;
    }
//用于获取上传后文件的文件名
    function getNewFileName(){
        return $this->newFileName;
    }
//上传如果失败,则调用这个方法,就可以查看错误报告
    function getErrorMsg() {
        return $this->errorMess;
    }
}



本帖最后由 七彩极 于 2017-8-9 14:48 编辑
从面向对象的设计角度评价,这个类代码还是半过程半面向对象的编程方式哈~!



面对对象貌似是编程一大难点、



‹‹ 上一贴:10道基础题,看你能拿多少分?   |   下一贴:死循环:看谁死得更惨! ››
  发新话题
快速回复主题
关于我们 | 诚聘英才 | 联系我们 | 网站大事 | 友情链接 |意见反馈 | 网站地图
Copyright©2005-2017 51CTO.COM
本论坛言论纯属发布者个人意见,不代表51CTO网站立场!如有疑义,请与管理员联系:bbs@51cto.com