PHP 之文件上傳類封裝

1、前端代碼php

<!doctype html>
<html lang="en">
<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>

2、php代碼html

<?php
/**
 * Created by PhpStorm.
 * User: Yang
 * Date: 2019/8/13
 * Time: 14:02
 */

include_once "./Upload.php";

$upload = new Upload();
if (!$upload->uploadFile("file")) {
    echo $upload->errorInfo;
}

3、類庫代碼前端

<?php

/**
 * Created by PhpStorm.
 * User: Yang
 * Date: 2019/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;
    }

}
相關文章
相關標籤/搜索