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

PHP 文件上傳中文文件名亂碼徹底解決:iconv 轉碼與隨機重命名雙重保障

     編輯:PHP 相關知識

問題根因

Windows 文件系統默認 GBK/GB2312,PHP 腳本常用 UTF-8,上傳時文件名編碼不一致導致亂碼或移動失敗。

方案一:iconv 編碼轉換(保留原文件名)

<?php
$originalName = $_FILES['file']['name'];

// UTF-8 腳本環境 → 系統 GBK 文件系統
$filesystemName = iconv("UTF-8", "GBK//IGNORE", $originalName);

// 移動文件
move_uploaded_file($_FILES['file']['tmp_name'], $uploadDir . $filesystemName);

// 存入數據庫時轉回 UTF-8
$dbName = iconv("GBK", "UTF-8//IGNORE", $filesystemName);

方案二:隨機重命名(推薦,避免編碼地獄)

<?php
function generateRandomFilename($originalName) {
    $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION));
    $timestamp = date("YmdHis");
    $random = mt_rand(10000, 99999);
    return "{$timestamp}_{$random}.{$ext}";
}

// 使用
$newName = generateRandomFilename($_FILES['file']['name']);
$savePath = $uploadDir . $newName;
move_uploaded_file($_FILES['file']['tmp_name'], $savePath);

// 數據庫存儲新文件名,原文件名單獨存一列備查
// 原文件名建議用 base64_encode 存儲或單獨字段

完整上傳處理流程

<?php
$allowedTypes = ['jpg','jpeg','png','gif','pdf','doc','docx'];
$maxSize = 2 * 1024 * 1024; // 2MB

$file = $_FILES['file'];
if ($file['error'] !== UPLOAD_ERR_OK) {
    die("上傳錯誤代碼: {$file['error']}");
}
if ($file['size'] > $maxSize) {
    die("文件過大,限制 {$maxSize} 字節");
}
$ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
if (!in_array($ext, $allowedTypes)) {
    die("不支持的文件類型: {$ext}");
}

// 方案二:隨機命名
$newName = date("YmdHis") . '_' . mt_rand(10000, 99999) . ".{$ext}";
$savePath = "uploads/{$newName}";

if (!move_uploaded_file($file['tmp_name'], $savePath)) {
    die("移動文件失敗,檢查目錄權限");
}

// 記錄原文件名(base64 避免編碼問題)
$originalNameB64 = base64_encode($file['name']);

// 入庫
// INSERT INTO uploads (filename, original_name, path, size, ext) VALUES (?, ?, ?, ?, ?)

編碼轉換對比表

方案優點缺點適用場景
iconv 轉碼保留用戶原文件名依賴服務器編碼,跨平台麻煩內部系統、用戶強需求
隨機重命名零編碼問題、防衝突、安全失去語義信息公開上傳、高併發、現代應用
UUID + 原名存庫完美平衡需額外字段企業級應用推薦

Windows 特殊注意

  • PHP 7.1+ 支持 mb_internal_encoding('UTF-8') 統一內部編碼
  • 文件系統實際為 UTF-16,但 PHP 通過 ANSI API 交互導致 GBK 假象
  • 最佳實踐:代碼統一 UTF-8,文件名落地用隨機名
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved