| 鍵名 | 含義 | 示例 |
| name | 客戶端原始文件名 | photo.jpg |
| type | MIME 類型(瀏覽器提供,不可信) | image/jpeg |
| size | 文件大小(位元組) | 24578 |
| tmp_name | 服務端臨時存儲路徑 | /tmp/phpA1b2C3 |
| error | 錯誤碼(0=成功,1=超過 php.ini 上限,2=超過表單 MAX_FILE_SIZE,3=部分上傳,4=無文件) | 0 |
三、副檔名提取:三種方法對比
$filename = $_FILES['userfile']['name'];
// 方法 1:pathinfo() —— 最推薦,支援多點文件名
$ext = pathinfo($filename, PATHINFO_EXTENSION); // 'jpg'
// 方法 2:strrchr + substr
$ext = substr(strrchr($filename, '.'), 1); // 'jpg'
// 方法 3:反轉字符串取首段(舊代碼常見)
$ext = strrev(explode('.', strrev($filename))[0]); // 'jpg'
建議:統一用 pathinfo(),再 strtolower() 標準化。
四、完整上傳處理流程
function processUpload($fileInputName, $allowedExt = ['jpg','jpeg','png','gif','pdf'], $maxSize = 2*1024*1024) {
if (!isset($_FILES[$fileInputName]) || $_FILES[$fileInputName]['error'] !== UPLOAD_ERR_OK) {
return ['success' => false, 'msg' => '上傳失敗或無文件'];
}
$file = $_FILES[$fileInputName];
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
// 1. 副檔名白名單
if (!in_array($ext, $allowedExt)) {
return ['success' => false, 'msg' => '不允許的文件類型'];
}
// 2. 文件大小
if ($file['size'] > $maxSize) {
return ['success' => false, 'msg' => '文件過大'];
}
// 3. MIME 類型二次驗證(可選,需 fileinfo 擴展)
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $file['tmp_name']);
finfo_close($finfo);
$allowedMime = ['image/jpeg','image/png','image/gif','application/pdf'];
if (!in_array($mime, $allowedMime)) {
return ['success' => false, 'msg' => '文件內容類型不匹配'];
}
// 4. 生成唯一文件名:時間戳 + 隨機數 + 原副檔名
$newName = date('YmdHis') . '_' . mt_rand(1000,9999) . '.' . $ext;
$destDir = __DIR__ . '/uploads/';
if (!is_dir($destDir)) mkdir($destDir, 0755, true);
$destPath = $destDir . $newName;
// 5. 移動文件
if (!move_uploaded_file($file['tmp_name'], $destPath)) {
return ['success' => false, 'msg' => '文件移動失敗'];
}
return ['success' => true, 'path' => $destPath, 'url' => '/uploads/' . $newName, 'ext' => $ext];
}
// 使用
$result = processUpload('userfile');
if ($result['success']) {
echo "上傳成功:" . $result['url'];
} else {
echo "錯誤:" . $result['msg'];
}
五、安全加固清單
- 禁用腳本執行權限:上傳目錄配置 Nginx/Apache 禁止 PHP 執行
location ~ \.php$ { deny all; }
- 文件名不信任用戶輸入:必須重命名,防止路徑遍歷、覆蓋系統文件
- MIME 雙重驗證:副檔名 +
finfo 實際內容檢測
- 大小限制雙層:php.ini
upload_max_filesize + 代碼邏輯驗證
- 隨機化存儲路徑:按日期分目錄
uploads/2023/10/15/,避免單目錄文件過多
- 病毒掃描:生產環境接入 ClamAV 或雲端安全 API
- 上一篇文章: PHP 合並 Discuz 用戶腳本:直接操作 uc_members 表的快速遷移方案
- 下一篇文章: WampServer 修改默認網站目錄完整教程:httpd.conf、wampmanager.ini、wampmanager.tpl 三文件聯動
Copyright ©
程式碼之家 All Rights Reserved