thinkphp5.3导入sql文件必须全程utf8mb4:sql文件需无bom的utf-8编码,dsn中显式写charset=utf8mb4,禁用set names,服务端及表结构同步设为utf8mb4,并按语句类型分别用db::execute()或db::query()执行。

ThinkPHP5.3 执行 SQL 文件(如导入 .sql 脚本)时,字符集问题不能靠“执行完再设”来补救——乱码在读取、解析、执行的每一步都可能已发生。关键不是“怎么执行 SQL 文件”,而是“执行前整个链路是否全程 utf8mb4”。
SQL 文件本身必须是 UTF-8 编码(无 BOM)
用编辑器(如 VS Code、Notepad++)确认文件编码为 UTF-8,不是 UTF-8-BOM 或 GBK。BOM 头会导致 SQL 解析失败或注释错位;GBK 文件里中文直接变成乱码字节,后续任何数据库设置都无效。
- 导出 SQL 时:phpMyAdmin 选“UTF-8 Unicode (utf8mb4)”,Navicat 勾选“UTF-8”并取消“BOM”
- 检查方式:用 xxd file.sql | head -n 2 查看开头三字节,ef bb bf 表示有 BOM,需另存为无 BOM UTF-8
数据库连接必须强制 utf8mb4(DSN 中写死)
TP5.3 的 database.php 配置中,'charset' => 'utf8mb4' 单独存在是无效的。必须把 charset=utf8mb4 显式写进 DSN 字符串里:
- 正确写法:
'dsn' => 'mysql:host=127.0.0.1;dbname=test;charset=utf8mb4' - 删掉配置中单独的
'charset' => ...行,避免干扰 - 验证是否生效:执行
Db::query("SELECT @@character_set_client, @@character_set_connection, @@character_set_results"),三个值都应返回utf8mb4
SQL 文件内不要依赖 SET NAMES
SQL 文件开头写 SET NAMES utf8mb4; 或 SET CHARSET utf8mb4; 是常见误区。TP5.3 执行 SQL 文件通常用 file_get_contents() + Db::execute() 分句执行,但 SET NAMES 只对当前连接会话临时生效,且无法保证每条语句都在同一连接上下文中执行(尤其开启多线程或连接池时)。
- 更可靠做法:确保服务端
character_set_server = utf8mb4(修改 my.cnf 并重启 MySQL) - 已有表字段也需升级:
ALTER TABLE `table_name` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; - SQL 文件中建表语句显式声明:
ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci
执行逻辑要分清“查”和“改”
SQL 文件常混有 CREATE、INSERT、SELECT 等语句。TP5.3 不支持自动识别语句类型:
-
Db::execute()只能用于INSERT/UPDATE/DELETE/CREATE/DROP类语句,返回影响行数 -
Db::query()仅用于SELECT/SHOW/EXPLAIN,返回数组;误用于 DDL 会静默返回空数组,导致后续逻辑断裂 - 建议:先用正则或简单字符串判断首单词(
preg_match('/^\s*(SELECT|SHOW|EXPLAIN)/i', $sql)),再分发调用
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











