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

PHP 單文件上傳完整實現:驗證、安全、唯一命名與目錄管理

     編輯:PHP 相關知識

PHP 單文件上傳完整實現:驗證、安全、唯一命名與目錄管理

將表單與處理邏輯合於單文件,涵蓋錯誤碼判斷、類型/大小驗證、HTTP 上傳檢查、唯一文件名生成、目錄自動創建、移動保存全流程。

HTML 表單

<form action="upload.php" method="post" enctype="multipart/form-data">
    請選擇要上傳的文件: <input type="file" name="myfile"/><br/><br/>
    <input type="submit" value="submit" />
    <input type="hidden" name="MAX_FILE_SIZE" value="5982"/>
</form>

enctype="multipart/form-data" 必須設置。隱藏域 MAX_FILE_SIZE 為瀏覽器端輔助限制(不可靠,服務端必須再驗證)。

PHP 處理邏輯

<?php
if (!empty($_FILES)) {
    header('Content-Type: text/html; charset=utf-8');
    $file = $_FILES['myfile'];

    // 1. 上傳錯誤碼檢查
    if ($file['error'] > 0) {
        $msg = [
            1 => '超過 php.ini upload_max_filesize',
            2 => '超過表單 MAX_FILE_SIZE',
            3 => '文件部分上傳',
            4 => '未選擇文件',
            6 => '找不到臨時目錄',
            7 => '寫入失敗',
            8 => '擴展中斷上傳',
        ];
        exit($msg[$file['error']] ?? '未知錯誤');
    }

    // 2. 擴展名白名單
    $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
    $allow = ['txt','html','png','gif','jpeg','jpg'];
    if (!in_array($ext, $allow)) exit('文件類型不允許');

    // 3. 大小限制(2MB)
    if ($file['size'] > 2*1024*1024) exit('文件過大');

    // 4. 確認 HTTP POST 上傳
    if (!is_uploaded_file($file['tmp_name'])) exit('非法上傳方式');

    // 5. 唯一文件名:md5(uniqid(microtime(true), true)) + 擴展名
    $newName = md5(uniqid(microtime(true), true)) . '.' . $ext;

    // 6. 目標目錄自動創建
    $dir = 'uploads';
    if (!file_exists($dir)) {
        mkdir($dir, 0777, true);
        chmod($dir, 0777);
    }
    $dest = $dir . '/' . $newName;

    // 7. 移動文件
    if (!move_uploaded_file($file['tmp_name'], $dest)) {
        exit('文件保存失敗');
    }

    echo '上傳成功,保存為:' . $newName;
}
?>

安全加固清單

  1. 雙重驗證:前端 JS + 後端 PHP,後端為準。
  2. 類型檢查:除擴展名外,建議用 finfo_file 檢測 MIME 類型。
  3. 存儲隔離:上傳目錄設為不可執行(Nginx/Apache 配置 php_flag engine off)。
  4. 文件名去特徵化:不保留原始文件名,防止路徑遍歷、覆蓋、編碼攻擊。
  5. 大小限制:php.ini 設定 upload_max_filesize、post_max_size 並與代碼一致。

常見問題排查

  • move_uploaded_file 失敗:檢查目錄權限、磁盤空間、open_basedir 限制。
  • 上傳大文件報錯:調整 max_execution_time、memory_limit、post_max_size。
  • 中文文件名亂碼:確保頁面、PHP、文件系統編碼一致(UTF-8),或上傳前轉碼。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved