PHP从TXT(CSV)导入MySQL时重音字符显示为问号的编码问题
问题
我有一个名为ADDEDA.TXT的文件(实际为CSV格式),解析后导入MySQL时,重音字符显示为问号。我尝试过用$content = encode_utf8($content);和mb_convert_encoding($data, 'UTF-8');转换编码,调用自定义的detectFileEncoding函数检测编码时,结果显示为BASE64。函数代码如下:
function detectFileEncoding($filePath){ $fopen=fopen($filePath,'r'); $row = fgets($fopen); $encodings = mb_list_encodings(); $encoding = mb_detect_encoding( $row, "UTF-8, ASCII, Windows-1252, Windows-1254" );//these are my favorite encodings if($encoding !== false) { $key = array_search($encoding, $encodings) !== false; if ($key !== false) unset($encodings[$key]); $encodings = array_values($encodings); } $encKey = 0; while ($row = fgets($fopen)) { if($encoding == false){ $encoding = $encodings[$encKey++]; } if(!mb_check_encoding($row, $encoding)){ $encoding =false; rewind($fopen); } } return $encoding; }
解决方案
1. 先处理BASE64解码
既然检测出文件是BASE64编码,第一步必须先解码内容,再进行编码转换和后续处理:
// 读取文件内容 $content = file_get_contents('ADDEDA.TXT'); // 尝试BASE64解码,第二个参数确保解码失败时返回false $decodedContent = base64_decode($content, true); if ($decodedContent !== false) { // 解码成功,后续处理解码后的内容 $content = $decodedContent; }
2. 修复编码检测函数
原函数存在逻辑错误(比如将布尔值赋值给$key导致unset操作异常),且未优先检测BASE64。以下是优化后的检测函数:
function detectFileEncoding($filePath) { $content = file_get_contents($filePath); // 优先检测BASE64编码 if (base64_decode($content, true) !== false) { return 'BASE64'; } // 先检测常用编码 $priorityEncodings = ["UTF-8", "ASCII", "Windows-1252", "Windows-1254"]; foreach ($priorityEncodings as $encoding) { if (mb_check_encoding($content, $encoding)) { return $encoding; } } // 尝试所有支持的编码 $allEncodings = mb_list_encodings(); foreach ($allEncodings as $encoding) { if (mb_check_encoding($content, $encoding)) { return $encoding; } } return false; }
3. 正确转换编码并导入MySQL
解码并检测到原编码后,转换为UTF-8(推荐用utf8mb4兼容更多字符),同时确保MySQL端编码配置正确:
// 获取解码后的内容编码 $encoding = detectFileEncoding('ADDEDA.TXT'); if ($encoding === 'BASE64') { $content = base64_decode(file_get_contents('ADDEDA.TXT'), true); // 重新检测解码后的内容编码 $encoding = detectFileEncoding('ADDEDA.TXT'); } // 转换为UTF-8 $utf8Content = mb_convert_encoding($content, 'UTF-8', $encoding); // MySQL连接时设置编码为utf8mb4 // mysqli示例 $conn = mysqli_connect('localhost', 'user', 'pass', 'db'); mysqli_set_charset($conn, 'utf8mb4'); // PDO示例 $dsn = 'mysql:host=localhost;dbname=db;charset=utf8mb4'; $conn = new PDO($dsn, 'user', 'pass'); // 后续执行导入逻辑即可
4. MySQL端编码配置检查
- 数据库和表的字符集设置为
utf8mb4,排序规则设为utf8mb4_unicode_ci - 确保导入时的SQL语句或CSV导入工具(如LOAD DATA INFILE)指定字符集为UTF-8
内容的提问来源于stack exchange,提问作者Marc Lef
相关产品推荐
相关产品推荐

