PHP 文件上傳操作類

来源:https://www.cnblogs.com/Super-Lee/archive/2020/04/29/12804069.html
-Advertisement-
Play Games

[TOC] 前言 今天在公司無事,就搞了下文件上傳的東東,方便自己的學習,和今後的使用,目前只支持單文件上傳。下麵是代碼部分,也可以訪問我的 "Gitee" 或 "Github" ,不想看代碼的童鞋可以直接 "下載]。。。(算了,討厭百度雲,如果有需要的話留言)代碼使用,使用方法請[點擊" 代碼 使 ...


目錄

前言

今天在公司無事,就搞了下文件上傳的東東,方便自己的學習,和今後的使用,目前只支持單文件上傳。下麵是代碼部分,也可以訪問我的 GiteeGithub,不想看代碼的童鞋可以直接[下載]。。。(算了,討厭百度雲,如果有需要的話留言)代碼使用,使用方法請點擊

代碼

<?php

namespace E;

class FileUpload
{
    /**
     * @var $name 上傳文件標記名
     */
    protected $name = 'file';

    /**
     * @var $ext 所允許的擴展名
     */
    protected $exts  = [];

    /**
     * @var $file 上傳的文件資源
     */
    protected $file = null;

    /**
     * @var $upload_success 是否上傳成功標誌
     */
    protected $upload_success = false;

    /**
     * @var $max_size 上傳文件所允許的大小,單位為 M
     */
    protected $max_size = 2;

    /**
     * @var $error_code 錯誤碼
     */
    protected $error_code = 0;

    /**
     * @var $error_msg 錯誤信息
     */
    protected $error_msg = '';

    /**
     * @var $file_ext 文件擴展名
     */
    protected $file_ext = '';

    /**
     * @var $type 文件類型,預設為任意類型
     */
    protected $type = 'file';

    protected const ERR_OK         = 0;
    protected const ERR_FILE_SIZE  = 1;
    protected const ERR_FORM_SIZE  = 2;
    protected const ERR_PARTIAL    = 3;
    protected const ERR_NO_FILE    = 4;
    protected const ERR_FILE_EXIST = 5;
    protected const ERR_NO_TMP_DIR = 6;
    protected const ERR_CANT_WRITE = 7;
    protected const ERR_FILE_TYPE  = 8;

    /**
     * 配置上傳信息
     *
     * @param array $arr
     * @return E\FileUpload
     */
    public function config($arr)
    {
        foreach ($arr as $key => $val) {
            if (property_exists($this, $key)) {
                $this->$key = $val;
            }
        }
        return $this;
    }

    /**
     * 進行文件上傳操作
     *
     * @return E\FileUpload
     */
    public function upload()
    {
        $this->file     = $this->getFile();
        $this->file_ext = strrchr($this->file['name'], '.');

        $this->upload_success = !($this->uploadError() || $this->overMaxSize() || $this->notAllowType());

        return $this;
    }

    /**
     * 判斷文件是否上傳成功
     * 
     * @return boolean
     */
    public function uploadSuccess()
    {
        return $this->upload_success;
    }

    /**
     * 保存已上傳的文件
     *
     * @param string $path
     * @param string $file_name
     *
     * @return boolean
     */
    public function save($path, $file_name = '')
    {
        if (!$this->uploadSuccess()) {
            return false;
        }

        // 判斷文件夾是否存在,如果不存在,新建一個文件夾
        if (!is_dir($path)) {
            mkdir($path);
        }

        // 獲取文件名,不包含尾碼
        $file_name = $file_name ?: 'e_' . time() . mt_rand(10000, 99999);

        $file = rtrim($path, '/') . '/' . $file_name . $this->file_ext;

        // 判斷文件是否存在
        if (file_exists($file)) {
            $this->error_code = self::ERR_FILE_EXIST;
            return false;
        }

        if (move_uploaded_file($this->file['tmp_name'], $file)) {
            return true;
        }

        // 文件未上傳成功,出現未知錯誤
        $this->error_code = -1;
        return false;
    }

    /**
     * 返回錯誤碼
     * 
     * @return integer
     */
    public function errorCode()
    {
        return $this->error_code;
    }

    /**
     * 返回錯誤信息
     *
     * @return string
     */
    public function errorMsg()
    {
        !$this->error_msg && $this->setErrorMsgByCode($this->error_code);

        return $this->error_msg;
    }

    /**
     * 獲取上傳文件
     * 
     * @return mixed
     */
    protected function getFile()
    {
        return $_FILES[$this->name];
    }

    /**
     * 判斷是否上傳錯誤
     * 
     * @return boolean
     */
    protected function uploadError()
    {
        $this->error_code = $this->file['error'];

        return (bool)$this->file['error'];
    }

    /**
     * 根據錯誤代碼設置錯誤信息
     *
     * @param  int $code
     */
    protected function setErrorMsgByCode($code)
    {
        $msg_arr = [
            '',
            '上傳文件最大為 ' . $this->getMaxSize() . 'M',
            '上傳文件過大',
            '文件只有部分被上傳',
            '沒有文件被上傳',
            '文件已存在',
            '文件丟失',
            '文件寫入失敗',
            '只能上傳' . implode(',', $this->exts) . '類型的文件'
        ];

        $this->error_msg = $msg_arr[$code] ?? '未知錯誤';
    }

    /**
     * 獲取上傳文件所限制的最大大小
     * 
     * @return int
     */
    protected function getMaxSize()
    {
        return min($this->max_size, (int)ini_get('upload_max_filesize'));
    }

    /**
     * 判斷文件是否超出限制大小
     *
     * @return boolean
     */
    protected function overMaxSize()
    {
        if ($this->file['size'] > $this->getMaxSize() * 1024 * 1024 * 8) {
            $this->error_code = self::ERR_FILE_SIZE;
            return true;
        }
        return false;
    }

    /**
     * 通過類型獲取尾碼名數組
     *
     * @return array
     */
    protected function getExtsByType()
    {
        $exts_arr = [
            'image' => ['jpg', 'jpeg', 'png', 'gif'],
            'file'  => [],
            'zip'   => ['zip', 'rar', '7z']
        ];

        return $exts_arr[$this->type] ?? [];
    }

    /**
     * 判斷是否是允許的類型
     * 
     * @return boolean
     */
    protected function notAllowType()
    {
        $this->exts = $this->exts ?: $this->getExtsByType();

        if (!$this->exts) return false;

        if (preg_match('/^\.' . implode('|', $this->exts) . '$/i', $this->file_ext)) {
            return false;
        }

        $this->error_code = self::ERR_FILE_TYPE;
        return true;
    }
}

使用方法

  1. 引入文件
include 'FileUpload.class.php';
  1. 實例化類
$uploader = new E\FileUpload();
  1. 配置
$uploader->config([
    'name'      => 'file',
    'exts'      => ['jpg'],
    'type'      => 'image',
    'max_size'  => 2,
]);

配置項的說明:

配置項 說明
name 是 HTML 中 input 的 name,例如: <input type="file" name="file">,預設是 file
exts 所允許上傳的文件擴展名,類型為數組,預設是任何類型的文件
type 上傳文件類型,可以通過設置 type 屬性,設置允許上傳類型,預設為 file,目前可選類型有:file 全部文件類型,image 圖片類型, zip 壓縮包,註意:exts優先順序高於 type,即如果設置了 type 為 file,exts 為 ['jpg'] 時,也還是只能上傳 jpg 類型的文件的
max_size 所允許上傳的大小,單位為 M,預設為 2M
  1. 上傳
$uploader->upload();
  1. 保存
$uploader->save('./uploads/', 'test')

save 方法的返回值是一個布爾值,上傳成功返回 true,失敗返回 false,可以根據返回的狀態進行相應的操作,如果失敗,可以使用 errorCode() 方法獲取錯誤代碼,使用 errorMsg() 方法獲取錯誤信息。

save 方法的第一個參數為必填參數,是要保存的路徑,第二個參數是文件名,可選,如果不填,則會自動生成,生成規則: e_ 連接上當前時間的時間戳再連接5位隨機數

也可以使用鏈式操作:

$uploader->upload()->save('./uploads/', 'test');

錯誤碼說明

錯誤碼 說明
0 無錯誤
1 上傳文件超出限制大小
2 上傳文件超出 form 表單所設置的 MAX_FILE_SIZE,也是文件過大
3 文件只有部分被上傳
4 沒有文件被上傳
5 存在同名文件
6 文件丟失
7 文件寫入失敗
8 上傳的文件類型不被允許
-1 未知錯誤

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • #! /usr/bin/env python#Version: pyyhon 3.x#Author : Syno''' 1st layer: chinese provinces Anhui 2nd layer: Hefei 3rd layer: Jingkai Area Binghu Area... ...
  • 問題描述 生產者消費者問題(英語:Producer-consumer problem),也稱有限緩衝問題(英語:Bounded-buffer problem),是一個多進程同步問題的經典案例。 該問題描述了共用固定大小緩衝區的兩個進程——即所謂的“生產者”和“消費者”——在實際運行時會發生的問題。生 ...
  • 本文的模型使用了C++工具箱dlib基於深度學習的最新人臉識別方法,基於戶外臉部數據測試庫Labeled Faces in the Wild 的基準水平來說,達到了99.38%的準確率。 dlib:http://dlib.net/ 數據測試庫Labeled Faces in the Wild:htt ...
  • 1 #include <iostream> 2 3 using namespace std; 4 5 class Matrix 6 { 7 private: 8 int a,b; 9 int arr[100][100]; 10 public: 11 Matrix() 12 { 13 for(int ...
  • 問題:Mac,php7.2,nginx 重啟php-fpm,多次運行killall php-fpm,或者一個一個的kill -9之後,再查看進程ps aux | grep php-fpm,php-fpm進程還在…… 參考網址:http://blog.haohtml.com/archives/1897 ...
  • 場景: 有一個表中的某一列,你需要獲取到這一列的所有值,你怎麼操作? 解決辦法: 有一個model為:Event 方式一: 方式一獲取到的是一個 ,內容是鍵值對構成的,鍵為表的列名,值為對應的每個值。 方式二: 方式二獲取到的也是一個 ,但是內容是元祖形式的查詢列的值。 但是我們想要的是這一列的值呀 ...
  • String 字元串 一個字元串是由一系列字元組成的。其中每個字元等同於一個位元組。這意味著 PHP 只能支持 256 的字元集,因此不支持 Unicode 。 語法 一個字元串可以用 4 種方式表達: 單引號 雙引號 單引號 一個最簡單的字元串是用單引號包起來的。可以再前面加反斜杠(\)來轉義。例如 ...
  • 我覺得我生活在這世上二十多年裡,去過最多的餐廳就是肯德基小時候逢生日必去,現在長大了,肯德基成了我的日常零食下班後從門前路過餓了便會進去點分黃金雞塊或者小吃拼盤早上路過,會買杯咖啡。主要快捷美味且飽腹,而且到處都是總是會路過,現在只要一餓,心心念念便是肯德基的味道 環境介紹 python 3.6 p ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...