PHP读取UTF-8文件导入MySQL后字符间出现�替换字符求助
问题解决思路
1. 先确认文件实际编码
用VS Code、Notepad++这类编辑器打开TSV文件,查看编码格式。如果是UTF-16带BOM的格式,直接转成UTF-8无BOM格式后再导入。
2. 强制设置数据库连接编码
你的代码里没指定数据库连接的字符集,这是核心问题之一。在建立数据库连接后,立即执行以下语句:
$dbconn->query("SET NAMES utf8mb4"); $dbconn->query("SET CHARACTER SET utf8mb4");
选择utf8mb4是因为它支持所有UTF-8字符(包括ë这类特殊字符),比MySQL原生的utf8兼容性更强。
3. 改用更可靠的文件读取与数据处理方式
file()函数容易因换行符、编码问题导致读取异常,换成fgetcsv处理TSV更稳妥,同时支持指定编码。另外,用预处理语句代替手动拼接SQL,既能避免注入风险,还能让数据库驱动自动处理编码:
$handle = fopen($dir . '/' . $file, 'r'); // 跳过表头行 fgetcsv($handle, 0, "\t"); while (($arr = fgetcsv($handle, 0, "\t")) !== false) { // 预处理字段:如果确认文件是UTF-16,解开下面的注释转码 // foreach ($arr as &$field) { // $field = mb_convert_encoding($field, 'UTF-8', 'UTF-16LE'); // $field = trim($field); // } // 生成占位符,执行预处理插入 $placeholders = implode(',', array_fill(0, count($arr), '?')); $stmt = $dbconn->prepare("INSERT INTO `$table` VALUES($placeholders)"); $stmt->execute($arr); } fclose($handle);
4. 检查数据库表的字符集配置
确保表和所有字段的字符集为utf8mb4,排序规则可选utf8mb4_unicode_ci或utf8mb4_general_ci。用以下SQL查看表配置:
SHOW CREATE TABLE `your_table_name`;
如果配置不对,执行修改语句:
ALTER TABLE `your_table_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
核心原因解析
你遇到的“每隔一个字符出现�”,本质是单字节UTF-8字符被错误识别为双字节编码(如UTF-16)解析,或者数据库连接未用UTF-8编码,导致正常字符被拆分后,空字节被替换成了占位符。
内容的提问来源于stack exchange,提问作者Bill Henderson
相关产品推荐
相关产品推荐

