PHP 多檔案上傳時 $_FILES 呈現「欄位優先」的多維結構,處理起來不直觀。本文提供一個實用的重組函數,將其轉換為「檔案優先」的單層陣列,方便迴圈處理每個上傳檔案。
// 表單: x3
$_FILES['UpLoadFile'] = array(
'name' => array('a.jpg', 'b.png', 'c.gif'),
'type' => array('image/jpeg', 'image/png', 'image/gif'),
'tmp_name' => array('/tmp/php1', '/tmp/php2', '/tmp/php3'),
'error' => array(0, 0, 0),
'size' => array(1234, 5678, 9012),
);
$files = array(
0 => array('name'=>'a.jpg', 'type'=>'image/jpeg', 'tmp_name'=>'/tmp/php1', 'error'=>0, 'size'=>1234),
1 => array('name'=>'b.png', 'type'=>'image/png', 'tmp_name'=>'/tmp/php2', 'error'=>0, 'size'=>5678),
2 => array('name'=>'c.gif', 'type'=>'image/gif', 'tmp_name'=>'/tmp/php3', 'error'=>0, 'size'=>9012),
);
<?php
function reorganizeFilesArray($files) {
$result = array();
$keys = array_keys($files); // name, type, tmp_name, error, size
$count = count($files[$keys[0]]);
for ($i = 0; $i < $count; $i++) {
$file = array();
foreach ($keys as $key) {
$file[$key] = $files[$key][$i];
}
$result[] = $file;
}
return $result;
}
// 使用範例
if (!empty($_FILES['UpLoadFile'])) {
$uploadFiles = reorganizeFilesArray($_FILES['UpLoadFile']);
foreach ($uploadFiles as $file) {
if ($file['error'] === UPLOAD_ERR_OK) {
move_uploaded_file($file['tmp_name'], 'uploads/' . $file['name']);
echo "上傳成功: {$file['name']}<br>";
} else {
echo "上傳失敗: {$file['name']} (錯誤碼: {$file['error']})<br>";
}
}
}
?>
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>多檔上傳測試</title></head><body>
<form action="" method="post" enctype="multipart/form-data">
<input name="UpLoadFile[]" type="file" /><br>
<input name="UpLoadFile[]" type="file" /><br>
<input name="UpLoadFile[]" type="file" /><br>
<input type="submit" value="上傳" />
</form>
<?php
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
echo '<h3>原始 $_FILES 結構</h3>';
echo '<pre>'; print_r($_FILES['UpLoadFile']); echo '</pre>';
$files = reorganizeFilesArray($_FILES['UpLoadFile']);
echo '<h3>重組後結構</h3>';
echo '<pre>'; print_r($files); echo '</pre>';
}
?>
</body></html>
<?php
function reorganizeAllFiles() {
$all = array();
foreach ($_FILES as $fieldName => $files) {
if (is_array($files['name'])) {
$all[$fieldName] = reorganizeFilesArray($files);
} else {
// 單檔案欄位轉為統一格式
$all[$fieldName] = array($files);
}
}
return $all;
}
// 使用
$allFiles = reorganizeAllFiles();
foreach ($allFiles as $fieldName => $files) {
echo "欄位: $fieldName<br>";
foreach ($files as $file) {
// 統一處理邏輯
}
}
?>
| 常數 | 值 | 說明 |
|---|---|---|
| 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 | 缺少暫存目錄 |
| UPLOAD_ERR_CANT_WRITE | 7 | 寫入磁碟失敗 |
| UPLOAD_ERR_EXTENSION | 8 | PHP 擴展阻止上傳 |
$file['error'] === UPLOAD_ERR_OK 再處理move_uploaded_file() 而非 copy() 確保安全uniqid() . '_' . basename($file['name']) 避免衝突finfo_file() 檢測真實 MIME 型別將 $_FILES 重組為檔案優先結構,能大幅簡化多檔案上傳的處理邏輯,減少索引錯誤。建議將重組函數封裝至共用工具庫,專案中統一呼叫。