PHP上传含日文字符文件时数据库存储文件名乱码问题咨询
问题排查解决步骤
- 第一步:确认数据库连接编码配置正确
绝大多数类似问题都是PDO连接未指定编码导致的,需在数据库连接的DSN中明确指定utf8mb4编码,示例配置如下:
// 错误写法(未指定charset) $conn = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass'); // 正确写法 $conn = new PDO('mysql:host=localhost;dbname=testdb;charset=utf8mb4', 'user', 'pass');
如果用的是旧版mysqli扩展,也需要执行编码设置语句:$conn->set_charset('utf8mb4');
- 第二步:校验上传文件名的原始编码
前端上传文件时,部分旧客户端或日文系统可能会默认用Shift-JIS编码传递文件名,而非UTF-8,可先在插入数据库前加日志检测编码:
// 输出文件名的编码类型,确认是否为UTF-8 var_dump(mb_detect_encoding($file['name'], ['UTF-8', 'SJIS', 'EUC-JP', 'ASCII']));
如果检测结果为非UTF-8编码,需手动转码后再存入数据库:
$this->file_name = mb_convert_encoding($file['name'], 'UTF-8', 'SJIS');
- 第三步:确认表、字段的实际编码配置
仅修改库级排序规则不会自动生效于已创建的表和字段,需执行SQL查看file_name字段的实际编码:
SHOW FULL COLUMNS FROM data_file;
如果Collation列不是utf8mb4_unicode_ci之类的utf8mb4开头值,需要单独修改字段编码:
ALTER TABLE data_file MODIFY COLUMN file_name VARCHAR(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci NOT NULL;
第四步:排除显示端干扰
不要仅通过phpMyAdmin的显示判断是否乱码,可直接在服务器上通过mysql命令行工具执行查询语句查看字段值,如果命令行查询结果正常,说明是phpMyAdmin本身的页面编码配置错误,不是数据存储问题。第五步:定位问题环节
可直接在代码中写死日文文件名写入数据库,验证是否会出现乱码:
// 测试用硬编码文件名 $testFileName = "さくらテスト.txt"; // 插入到数据库后查询结果,如果正常说明问题出在上传文件名的获取环节,否则为数据库配置问题
内容的提问来源于stack exchange,提问作者Vince
相关产品推荐
相关产品推荐

