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

PHP 檔案上傳完整實戰:表單構建、類型驗證、隨機命名、預覽回顯

     編輯:PHP 綜合知識

前端表單三大關鍵點

<form method="post" action="upload.php" enctype="multipart/form-data">
  <input type="hidden" name="MAX_FILE_SIZE" value="2000000">  <!-- 限制 2MB -->
  <input name="file" type="file">
  <input type="submit" value="上傳">
</form>
屬性說明
enctype="multipart/form-data"必須,否則 $_FILES 為空
MAX_FILE_SIZE客戶端提示上限,實際以 php.ini upload_max_filesize 為準
type="file"瀏覽器顯示「選擇檔案」按鈕

後端處理流程 upload.php

<?php
$uploaddir = './files/';                 // 儲存目錄,需可寫
$allowExt  = ['jpg','gif','bmp','jpeg','png']; // 允許副檔名

// 取得副檔名
function fileext($filename) {
    return substr(strrchr($filename, '.'), 1);
}

// 產生隨機檔名:CR- + 10 位英數
function random($len = 10) {
    $chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789abcdefghijklmnopqrstuvwxyz';
    $str = 'CR-';
    for ($i = 0; $i < $len; $i++) {
        $str .= $chars[mt_rand(0, strlen($chars)-1)];
    }
    return $str;
}

$ext = strtolower(fileext($_FILES['file']['name']));

// 1. 類型檢查
if (!in_array($ext, $allowExt)) {
    exit('僅允許上傳:' . implode(', ', $allowExt));
}

// 2. 組合目標路徑(避免重名)
$filename = explode('.', $_FILES['file']['name']);
do {
    $filename[0] = random(10);
    $newName = implode('.', $filename);
    $dest = $uploaddir . $newName;
} while (file_exists($dest));

// 3. 移動暫存檔
if (move_uploaded_file($_FILES['file']['tmp_name'], $dest)) {
    if (is_uploaded_file($_FILES['file']['tmp_name'])) {
        echo "<center>上傳成功!預覽:<br><img src='$dest'></center>";
        echo "<br><center><a href='javascript:history.back()'>繼續上傳</a></center>";
    } else {
        echo '上傳驗證失敗!';
    }
} else {
    echo '移動檔案失敗,請檢查目錄權限。';
}
?>

關鍵函數解析

  • strrchr($str, '.'):取最後一個 . 及其後內容(含點)
  • substr(..., 1):去掉點號,得純副檔名
  • mt_srand((double)microtime()*1e6):播種更強隨機數(PHP 4.2+ 可省略)
  • $_FILES['file']['tmp_name']:暫存路徑(系統自動清理)
  • move_uploaded_file():安全移動,自動檢查是否為 HTTP POST 上傳
  • is_uploaded_file():二次驗證,防偽造

常見坑與解決

現象原因對策
上傳大檔失敗php.ini upload_max_filesize / post_max_size 過小調大並重啟 PHP-FPM/Apache
中文檔名亂碼檔案系統編碼不一強制隨機命名(如本例)或 iconv 轉碼
權限拒絕目錄不可寫chmod 755 files/、確認 PHP-FPM 用戶權限
圖片無法預覽路徑錯誤 / 權限 / Nginx 靜態檔案配置用相對路徑、確認 location /files/ 允許存取

進階擴展方向

  1. 多檔上傳:<input name="files[]" type="file" multiple> + 迴圈處理
  2. 分片/斷點續傳:Plupload / WebUploader + 後端合併分片
  3. AJAX 無刷新:FormData + fetch() + 進度條 xhr.upload.onprogress
  4. 雲端儲存:上傳至 S3 / OSS / COS,回傳 CDN URL 入庫
  5. 圖片處理:Intervention Image / GD / Imagick 縮圖、水印、格式轉換

安全性清單

  • ✅ 白名單驗證副檔名 + MIME 類型(finfo_file)
  • ✅ 隨機檔名 + 存放非 Web 可執行目錄
  • ✅ 禁止 .php、.phtml 等腳本副檔名
  • ✅ Nginx/Apache 配置 location ~ \.php$ { deny all; } 於上傳目錄
  • ✅ 病毒掃描(ClamAV)或內容安全檢測

總結

檔案上傳看似簡單,實則涉及「前端編碼、PHP 配置、檔案系統權限、安全防護、效能優化」多個面向。本例以「隨機命名 + 白名單 + 移動驗證 + 圖片預覽」為核心流程,構建了最小可用的上傳閉環。掌握這套基礎後,再疊加分片、雲存、圖片處理等企業級能力,即可應對各類上傳場景。

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