专栏首页网页开发/美化PHP 之文件上传类封装

PHP 之文件上传类封装

一、前端代码

<!doctype html>
    <html>
    <head>
    <meta charset="UTF-8"/>
    <title>文件上传</title></head><body><form action="do.php" method="post" enctype="multipart/form-data">
    <input type="file" name="file" value=""><br>
    <input type="submit" value="上传文件"/><br></form></body></html>

二、php代码

<?php/**
 * Created by PhpStorm.
 * User: Lee
 * Date: 2020/8/13
 * Time: 14:02 */include_once "./Upload.php";$upload = new Upload();if (!$upload->uploadFile("file")) {    echo $upload->errorInfo;
}

三、类库代码

<?php/**
 * Created by PhpStorm.
 * User: Lee
 * Date: 2020/8/13
 * Time: 13:49 */class Upload
{    //文件上传路径
    protected $path = 'upload/';    //允许文件上传的后缀
    protected $allowSuffix = ['jpg', 'jpeg', 'gif', 'wbmp', 'png'];    //mime类型
    protected $allowMime = ['image/jpg', 'image/jpeg', 'image/gif', 'image/wbmp', 'image/png'];    //允许上传的大小
    protected $maxSize = 2 * 1024 * 1024;    //是否启用默认的前缀
    protected $isRandName = true;    //文件的前缀
    protected $prefix = 'up_';    //错误号和错误信息
    protected $errorNumber;    protected $errorInfo;    //文件的信息
    //文件名
    protected $oldName;    //文件的后缀
    protected $suffix;    //文件的大小
    protected $size;    //文件的mime
    protected $mime;    //文件的临时文件的路径
    protected $tmpName;    //文件新名字
    protected $newName;    /**
     * 构造方法
     * Upload constructor.
     * @param array $arr     */
    public function __construct($arr = [])
    {        foreach ($arr as $key => $value) {            $this->setOption($key, $value);
        }
    }    /**
     * 判断$key是不是我的成员属性,如果是就设置
     * @param $key
     * @param $value     */
    protected function setOption($key, $value)
    {        //得到所有的成员属性
        $keys = array_keys(get_class_vars(__CLASS__));        if (in_array($key, $keys)) {            $this->$key = $value;
        }
    }    /**
     * 文件上传函数
     * key 就是input框中的name属性值
     * @param $key
     * @return bool|string     */
    public function uploadFile($key)
    {        //判断有没有设置路径 path
        if (empty($this->path)) {            $this->setOption('errorNumber', -1);            return false;
        }        //判断该路径是否存在是否可写
        if (!$this->check()) {            $this->setOption('errorNumber', -2);            return false;
        }        //判断$_FILES里面的error信息是否为0,如果为0则说明文件信息在服务器端可以直接获取,提取信息保存到成员属性中
        $error = $_FILES[$key]['error'];        if ($error) {            $this->setOption('errorNumber', -3);            return false;
        } else {            //提取文件相关信息并且保存到成员属性中
            $this->getFileInfo($key);
        }        //判断文件的大小、mime、后缀是否符合
        if (!$this->checkSize() || !$this->checkMime() || !$this->checkSuffix()) {            return false;
        }        //得到新的文件名字
        $this->newName = $this->createNewName();        //判断是否是上传文件,并且是移动上传文件
        if (is_uploaded_file($this->tmpName)) {            if (move_uploaded_file($this->tmpName, $this->path . $this->newName)) {                return $this->path . $this->newName;
            } else {                $this->setOption('errorNumber', -7);                return false;
            }
        } else {            $this->setOption('errorNumber', -6);            return false;
        }
    }    /**
     * 检测文件夹是否存在,是否可写
     * @return bool     */
    protected function check()
    {        //文件夹不存在或者不是目录。创建文件夹
        if (!file_exists($this->path) || !is_dir($this->path)) {            return mkdir($this->path, 0777, true);
        }        //判断文件是否可写
        if (!is_writeable($this->path)) {            return chmod($this->path, 0777);
        }        return true;
    }    /**
     * 根据key得到文件信息
     * @param $key     */
    protected function getFileInfo($key)
    {        //得到文件的名字
        $this->oldName = $_FILES[$key]['name'];        //得到文件的mime类型
        $this->mime = $_FILES[$key]['type'];        //得到文件的临时文件
        $this->tmpName = $_FILES[$key]['tmp_name'];        //得到文件大小
        $this->size = $_FILES[$key]['size'];        //得到文件后缀
        $this->suffix = pathinfo($this->oldName)['extension'];
    }    /**
     * 判断文件大小
     * @return bool     */
    protected function checkSize()
    {        if ($this->size > $this->maxSize) {            $this->setOption('errorNumber', -3);            return false;
        }        return true;
    }    /**
     * 判断mime类型
     * @return bool     */
    protected function checkMime()
    {        if (!in_array($this->mime, $this->allowMime)) {            $this->setOption('errorNumber', -4);            return false;
        }        return true;
    }    /**
     * 判断后缀
     * @return bool     */
    protected function checkSuffix()
    {        if (!in_array($this->suffix, $this->allowSuffix)) {            $this->setOption('errorNumber', -5);            return false;
        }        return true;
    }    /**
     * 创建新名字
     * @return string     */
    protected function createNewName()
    {        if ($this->isRandName) {            $name = $this->prefix . uniqid() . '.' . $this->suffix;
        } else {            $name = $this->prefix . $this->oldName;
        }        return $name;
    }    /**
     * 读取不可访问属性的值时,__get() 会被调用。也就是,当想要获取一个类的私有属性,或者获取一个类并为定义的属性时。该魔术方法会被调用。
     * @param $name
     * @return string     */
    public function __get($name)
    {        if ($name == 'errorNumber') {            return $this->errorNumber;
        } elseif ($name == 'errorInfo') {            return $this->getErrorInfo();
        }
    }    /**
     * 获取错误信息
     * @return string     */
    protected function getErrorInfo()
    {        switch ($this->errorNumber) {            case -1:                $str = '文件路径没有设置';                break;            case -2:                $str = '文件不是目录或者不可写';                break;            case -3:                $str = '文件超过指定大小';                break;            case -4:                $str = 'mime类型不符合';                break;            case -5:                $str = '文件后缀不符合';                break;            case -6:                $str = '不是上传文件';                break;            case -7:                $str = '移动失败';                break;            case 1:                $str = '超出ini设置大小';                break;            case 2:                $str = '超出html表单大小';                break;            case 3:                $str = '文章只有部分上传';                break;            case 4:                $str = '没有文件上传';                break;            case 6:                $str = '找不到临时文件';                break;            case 7:                $str = '文件写入失败';                break;
        }        return $str;
    }
}

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • AntUI文字书写范例(util/writing)

    爱知汇
  • AntUI卡片Cards

    爱知汇
  • AntUI常规Forms表单

    爱知汇
  • 利用js实现输入框动态提示信息

    为了提高和用户的交互性,现在的输入框往往都采用输入信息自动提示的功能,类似于百度输入框中的提示功能。 设计思路是:在输入框input的组件下面放置一个div,这...

    林老师带你学编程
  • JavaScript 进阶教程(2)---面向对象实战之贪吃蛇小游戏

    上篇文章:https://blog.csdn.net/qq_23853743/article/details/108034430

    AlbertYang
  • 定时获取服务器时间戳的一个类(Typescript)

    我的博客即将同步至腾讯云+社区,邀请大家一同入驻:https://cloud.tencent.com/developer/support-plan?invite...

    lilugirl
  • php+laravel依赖注入知识点总结

    laravel容器包含控制反转和依赖注入,使用起来就是,先把对象bind好,需要时可以直接使用make来取就好。

    砸漏
  • 微信小程序之SelectorQuery

    在开发小程序展开全文组件时需要用到节点查询API - wx.createSelectorQuery() 来查询全文内容的高度。

    IMWeb前端团队
  • 从零开始学 Web 之 JavaScript 高级(一)原型,贪吃蛇案例

    由来:构造函数的问题。如果一个构造函数中有一个匿名方法,那么每实例化一个对象,然后在对象调用这个方法的时候,由于每个对象的方法都是各自的,所以每次调用这个方法的...

    Daotin
  • 从 0 到 1 实现 React 系列 —— 5.PureComponent 实现 && HOC 探幽

    本系列文章在实现一个 cpreact 的同时帮助大家理顺 React 框架的核心内容(JSX/虚拟DOM/组件/生命周期/diff算法/setState/Pur...

    牧云云

扫码关注云+社区

领取腾讯云代金券