首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

ThinkPHP 3.2 文件上傳核心類 \Think\Upload 完整使用教學

     編輯:PHP 相關知識

框架內建上傳類優勢

  • 零依賴,開箱即用
  • 支援多檔、多驅動 (本地、FTP、雲存儲)
  • 內建驗證、子目錄哈希、命名規則等企業級特性
  • 遵循 ThinkPHP 規範,與框架無縫整合

基本用法

<?php
namespace Home\Controller;
use Think\Controller;

class IndexController extends Controller {
    
    public function upload() {
        // 1. 實例化
        $upload = new \Think\Upload();
        
        // 2. 配置屬性
        $upload->maxSize = 3 * 1024 * 1024;     // 3MB
        $upload->exts = ['jpg', 'gif', 'png', 'jpeg'];
        $upload->rootPath = './Uploads/';        // 根目錄 (相對入口檔案)
        $upload->savePath = '';                  // 子目錄 (空則按日期自動建立)
        
        // 3. 執行上傳
        $info = $upload->upload();
        
        // 4. 結果處理
        if (!$info) {
            $this->error($upload->getError());
        } else {
            // $info 結構: ['field_name' => ['name','savename','savepath','ext','size','type',...]]
            foreach ($info as $file) {
                echo "檔案: {$file['name']} → 儲存: {$file['savepath']}{$file['savename']}<br>";
            }
            $this->success('上傳成功!');
        }
    }
}
?>

核心配置屬性完整表

屬性型別預設值說明
maxSizeint0 (不限制)最大檔案大小 (位元組)
extsarray[]允許副檔名 (不含點)
mimesarray[]允許 MIME 類型
rootPathstring./Uploads/儲存根目錄
savePathstring''子目錄,支援日期格式 Y/m/d
autoSubbooltrue是否自動建立子目錄
subNamestring/array['date','Ymd']子目錄命名規則
saveNamestring/array['uniqid','']檔案命名規則
saveExtstring''強制副檔名
replaceboolfalse同名檔案是否覆蓋
hashbooltrue是否生成 hash 目錄
callbackboolfalse是否啟用回調檢查
driverstringLocal儲存驅動 (Local/Ftp/Qiniu...)
driverConfigarray[]驅動配置參數

進階配置範例

1. 自訂命名:時間戳 + 隨機數

$upload->saveName = ['time', 'YmdHis'] . '_' . mt_rand(1000, 9999);
// 產生: 20240115143025_8765.jpg

2. 日期分層目錄結構

$upload->autoSub = true;
$upload->subName = ['date', 'Y/m/d'];
// 產生: ./Uploads/2024/01/15/

3. 多檔案上傳 (表單 name="files[]")

// 控制器同樣使用 $upload->upload()
// $info 將包含多個檔案資訊
if ($info) {
    foreach ($info as $field => $file) {
        // $field 為表單欄位名,多檔時通常為 0,1,2...
        echo "{$file['savename']} ({$file['size']} bytes)<br>";
    }
}

4. 回調函數驗證 (圖片尺寸、內容檢查)

$upload->callback = true;
// 需在同控制器定義 callback 方法
public function callback($file) {
    // $file 為單檔資訊陣列
    $imgInfo = getimagesize($file['tmp_name']);
    if ($imgInfo[0] > 2000 || $imgInfo[1] > 2000) {
        return '圖片尺寸不得超過 2000x2000';
    }
    // 檢查是否為真實圖片 (防偽裝)
    if (!in_array($imgInfo['mime'], ['image/jpeg','image/png','image/gif'])) {
        return '非法圖片格式';
    }
    return true; // 通過
}

5. 雲存儲驅動 (七牛雲範例)

$upload->driver = 'Qiniu';
$upload->driverConfig = [
    'accessKey' => 'your_ak',
    'secretKey' => 'your_sk',
    'domain' => 'https://cdn.yourdomain.com',
    'bucket' => 'your_bucket',
    'timeout' => 30,
];

前端表單關鍵點

<form action="<?php echo U('Index/upload'); ?>" method="post" enctype="multipart/form-data">
    <!-- 單檔 -->
    <input type="file" name="photo" accept="image/*">
    
    <!-- 多檔 -->
    <input type="file" name="files[]" multiple accept="image/*">
    
    <!-- 限制大小 (瀏覽器端提示,伺服器仍需驗證) -->
    <input type="hidden" name="MAX_FILE_SIZE" value="3145728">
    
    <button type="submit">上傳</button>
</form>

錯誤代碼對照表

常數代碼訊息
UPLOAD_ERR_OK0上傳成功
UPLOAD_ERR_INI_SIZE1超過 php.ini upload_max_filesize
UPLOAD_ERR_FORM_SIZE2超過 HTML MAX_FILE_SIZE
UPLOAD_ERR_PARTIAL3部分上傳
UPLOAD_ERR_NO_FILE4無檔案上傳
UPLOAD_ERR_NO_TMP_DIR6缺少暫存目錄
UPLOAD_ERR_CANT_WRITE7寫入失敗
UPLOAD_ERR_EXTENSION8擴展阻擋

常見問題與解決

問題原因解決
上傳大檔失敗php.ini 限制調大 upload_max_filesize, post_max_size, max_execution_time
中文檔名亂碼編碼不一致設定 saveName 強制重命名、或 mb_convert_encoding
權限錯誤目錄不可寫chmod 755 Uploads、檢查 PHP-FPM 用戶權限
nginx 413 錯誤client_max_body_sizenginx.conf 設定 client_max_body_size 20M;

最佳實踐封裝:Service 層

<?php
// Home/Service/UploadService.class.php
namespace Home\Service;
use Think\Upload;

class UploadService {
    private $upload;
    
    public function __construct(array $config = []) {
        $this->upload = new Upload($config);
    }
    
    public function image(string $field, array $options = []): array {
        $default = [
            'maxSize' => 5 * 1024 * 1024,
            'exts' => ['jpg','jpeg','png','gif','webp'],
            'savePath' => 'images/',
            'subName' => ['date', 'Y/m'],
        ];
        $this->upload->maxSize = $default['maxSize'];
        $this->upload->exts = $default['exts'];
        $this->upload->savePath = $default['savePath'];
        $this->upload->subName = $default['subName'];
        
        return $this->upload($field);
    }
    
    public function document(string $field): array {
        $this->upload->exts = ['pdf','doc','docx','xls','xlsx','txt'];
        $this->upload->savePath = 'documents/';
        return $this->upload($field);
    }
    
    private function upload(string $field): array {
        $info = $this->upload->upload();
        if (!$info) {
            throw new \Exception($this->upload->getError());
        }
        return isset($info[$field]) ? $info[$field] : array_values($info)[0];
    }
}

// 控制器使用
$service = new \Home\Service\UploadService();
try {
    $file = $service->image('avatar');
    // $file: ['name','savename','savepath','size','type',...]
    $user->avatar = $file['savepath'] . $file['savename'];
} catch (\Exception $e) {
    $this->error($e->getMessage());
}
?>

總結

ThinkPHP 3.2 的 \Think\Upload 類功能強大、配置靈活,掌握其核心屬性 (maxSize, exts, rootPath, savePath, saveName, subName, driver) 即可應對絕大多數上傳場景。建議在 Service 層封裝業務邏輯,控制器保持輕量。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved