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

PHP 文件上傳兩大核心實現方式:標準表單與 Base64 異步上傳

     編輯:PHP 相關知識

PHP 文件上傳實戰:標準 multipart/form-data 與 Base64 AJAX 兩大方案深度解析

文件上傳是 Web 開發高頻需求,主要分為兩類實現路徑:標準表單上傳(適合大文件、批量)與 Base64 編碼異步上傳(適合圖片預覽、壓縮)。本文將詳細拆解兩種方案的前後端協作細節。

方案一:標準 Input 表單上傳(multipart/form-data)

此為最通用、瀏覽器原生支援的方式,適用於任意類型、大體積文件,天然支援多文件批量上傳。

前端 HTML 關鍵點

<form enctype="multipart/form-data" method="post" action="upload.php">
  <input type="file" name="id_pic[]" accept="image/*" class="form-control" multiple />
  <input type="submit" value="上傳" />
</form>
  • enctype="multipart/form-data":必須,否則文件二進制數據不會發送。
  • accept="image/*":限制文件選擇框優先顯示圖片(MIME 類型過濾)。
  • multiple:允許一次選擇多個文件。
  • name="id_pic[]":陣列命名法,PHP 端將接收到結構化陣列。
  • 移動端可加 capture="camera" 直接喚起攝像頭。

不同 name 屬性下的 $_FILES 結構差異

同 name (陣列模式) name="id_pic[]":

array(1) {
  ["id_pic"]=> array(5) {
    ["name"]=> array(2) { [0]=> "1.jpg", [1]=> "2.jpg" }
    ["type"]=> array(2) { [0]=> "image/jpeg", [1]=> "image/jpeg" }
    ["tmp_name"]=> array(2) { [0]=> "C:\Windows\Temp\php7A7E.tmp", ... }
    ["error"]=> array(2) { [0]=> 0, [1]=> 0 }
    ["size"]=> array(2) { [0]=> 77357, [1]=> 56720 }
  }
}

不同 name (獨立模式) name="id_pic_1", name="id_pic_2":

array(2) {
  ["id_pic_1"]=> array(5) { ["name"]=> "1.jpg", ["type"]=> "image/jpeg", ... }
  ["id_pic_2"]=> array(5) { ["name"]=> "2.jpg", ["type"]=> "image/jpeg", ... }
}

獨立模式遍歷更方便。建議編寫統一轉換函數 dealFiles() 將陣列模式轉為統一的列表結構:

function dealFiles($files) {
    $fileArray = []; $n = 0;
    foreach ($files as $key => $file) {
        if (is_array($file['name'])) {
            $keys = array_keys($file);
            $count = count($file['name']);
            for ($i = 0; $i < $count; $i++) {
                $fileArray[$n]['key'] = $key;
                foreach ($keys as $_key) {
                    $fileArray[$n][$_key] = $file[$_key][$i];
                }
                $n++;
            }
        } else {
            $fileArray = $files; break;
        }
    }
    return $fileArray;
}

後端核心處理邏輯

  1. 安全檢測:驗證 MIME 類型、副檔名、文件簽名(魔數),防止偽裝腳本上傳。
  2. 大小限制:對比 $_FILES['size'] 與 php.ini 的 upload_max_filesize、表單隱藏域 MAX_FILE_SIZE。
  3. 目錄權限:確保目標目錄存在且可寫(is_writable())。
  4. 重命名存儲:使用 move_uploaded_file($tmp_name, $destination) 移動臨時文件。移動前可用 is_uploaded_file() 驗證合法性。多文件循環調用。

方案二:Base64 編碼 AJAX 異步上傳(主攻圖片)

利用 input 的 change 事件,配合 Canvas 壓縮圖片,再以 toDataURL() 生成 Base64 字串,經 AJAX POST 發送至後端。

核心原理

  1. 前端 FileReader 讀取文件 → Image 載入 → Canvas.drawImage() 繪製/壓縮。
  2. canvas.toDataURL('image/jpeg', quality) 輸出 Base64 Data URI(含 data:image/jpeg;base64, 前綴)。
  3. 前端發送 Base64 字串(可附帶 base64Len 供後端驗證完整性)。

後端 PHP 處理範例

<?php
// 接收純 Base64 字串(需去除 data URI 前綴)
$base64 = $_POST['img'];
if (strpos($base64, ',') !== false) {
    $base64 = substr($base64, strpos($base64, ',') + 1);
}
$binary = base64_decode($base64);
// 方式一:直接存檔
file_put_contents('upload/xxx.jpg', $binary);
// 方式二:GD 庫進一步處理
$img = imagecreatefromstring($binary);
// ... 處理後 imagejpeg($img, 'path');
?>

總結選型建議

場景推薦方案理由
大文件、視頻、文檔、批量上傳標準表單流式傳輸,不佔用記憶體編碼開銷,瀏覽器原生支援斷點續傳插件
頭像、圖片編輯、即時預覽、客戶端壓縮Base64 + Canvas可在上傳前預覽、裁剪、壓縮,減少頻寬;適合移動端弱網環境
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved