$_FILES 是 PHP 處理文件上傳的核心超全局數組。掌握其結構、錯誤碼含義及標準處理流程,是構建安全上傳功能的基礎。
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="hidden" name="MAX_FILE_SIZE" value="2097152"> <!-- 2MB,瀏覽器端輔助限制 -->
<input type="file" name="myFile">
<button type="submit">上傳</button>
</form>
假設輸入框 name="myFile",則 $_FILES['myFile'] 包含:
| 鍵名 | 說明 | 示例 |
|---|---|---|
name | 客戶端原始文件名 | photo.jpg |
type | 瀏覽器報告的 MIME 類型(不可信) | image/jpeg |
size | 文件大小(字節) | 102400 |
tmp_name | 服務端臨時存儲路徑 | /tmp/phpA1b2C3 |
error | 上傳錯誤碼(關鍵) | 0 |
error)完整對照表| 常量 | 值 | 含義 |
|---|---|---|
UPLOAD_ERR_OK | 0 | 上傳成功 |
UPLOAD_ERR_INI_SIZE | 1 | 超過 php.ini upload_max_filesize |
UPLOAD_ERR_FORM_SIZE | 2 | 超過表單 MAX_FILE_SIZE |
UPLOAD_ERR_PARTIAL | 3 | 文件部分上傳(網絡中斷) |
UPLOAD_ERR_NO_FILE | 4 | 未選擇文件 |
UPLOAD_ERR_NO_TMP_DIR | 6 | 缺少臨時目錄(PHP 5.0.3+) |
UPLOAD_ERR_CANT_WRITE | 7 | 寫入磁盤失敗(PHP 5.1.0+) |
UPLOAD_ERR_EXTENSION | 8 | 擴展中斷上傳(PHP 5.2.0+) |
<?php
// 1. 檢查錯誤碼
if ($_FILES['myFile']['error'] !== UPLOAD_ERR_OK) {
throw new Exception('上傳失敗,錯誤碼:' . $_FILES['myFile']['error']);
}
// 2. 驗證文件類型(不可信 $_FILES['type'],需二次檢測)
$finfo = new finfo(FILEINFO_MIME_TYPE);
$mime = $finfo->file($_FILES['myFile']['tmp_name']);
$allowed = ['image/jpeg', 'image/png', 'image/gif', 'application/pdf'];
if (!in_array($mime, $allowed)) {
throw new Exception('不允許的文件類型:' . $mime);
}
// 3. 驗證文件大小(雙重保險)
if ($_FILES['myFile']['size'] > 2 * 1024 * 1024) {
throw new Exception('文件過大');
}
// 4. 生成安全存儲路徑
$ext = pathinfo($_FILES['myFile']['name'], PATHINFO_EXTENSION);
$dest = '/var/uploads/' . bin2hex(random_bytes(16)) . '.' . $ext;
// 5. 移動文件(原子操作,內含 is_uploaded_file 驗證)
if (!move_uploaded_file($_FILES['myFile']['tmp_name'], $dest)) {
throw new Exception('文件保存失敗');
}
// 6. 設置權限、記錄日誌、返回結果
chmod($dest, 0644);
echo json_encode(['success' => true, 'path' => $dest]);
?>
putenv('TMPDIR=...') 無法修改上傳臨時目錄,需在 php.ini 設置 upload_tmp_dir$_FILES 結構為多維數組,需遞歸遍歷遵循此流程可構建健壯、安全的文件上傳功能。