laravel insert中文报general error的根本原因是字符集不一致——需确保character_set_client、connection、results三者均为utf8mb4,且表字段实际编码也为utf8mb4;通过.env、config/database.php配置charset与collation,再用alter table修正表结构即可解决。

解决Laravel INSERT中文报General error问题,核心是切断字符集错位链——当character_set_client、character_set_connection、character_set_results三者不全为utf8mb4,或表字段实际编码未生效时,INSERT中文会触发SQLSTATE[HY000]: General error而非明确的乱码提示。
确认当前连接层字符集是否真正生效
别信.env里写的DB_CHARSET=utf8mb4,运行时可能被覆盖。连上 MySQL 后立刻执行:
SHOW VARIABLES LIKE 'character_set%';
重点盯这三项:【character_set_client、character_set_connection、character_set_results 必须全部显示 utf8mb4】。只要其中一个是 latin1 或旧版 utf8(即 utf8mb3),INSERT 中文就会卡在连接层解码阶段,直接抛 General error。
如果发现 client 是 latin1,说明 Laravel 没有把 charset 带进连接参数——哪怕 .env 里写了,也白搭。
强制连接层使用 utf8mb4
方法一:修改 .env 文件,确保这一行存在且无空格、无注释:
DB_CHARSET=utf8mb4
方法二:在 config/database.php 的 mysql 配置块中显式追加:
'charset' => 'utf8mb4', 'collation' => 'utf8mb4_unicode_ci',
⚠️ 注意:仅改 charset 不够,collation 必须同步匹配,否则某些索引操作会失败。
方法三:命令行调试时,用 mysql 客户端直连验证:
mysql --default-character-set=utf8mb4 -u root -p
连进去后立刻执行 SHOW VARIABLES LIKE 'character_set_client';,确认返回 utf8mb4。这步能排除 Laravel 外部环境干扰。
修复表字段真实编码(不是只改声明)
第一步:检查目标表字段当前实际编码
SHOW CREATE TABLE your_table_name;
看 CREATE TABLE 语句里每个中文字段(如 title VARCHAR(255))后面有没有 CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci。没有?说明字段还是旧编码。
第二步:对整张表执行 CONVERT TO(适用于字段不多、数据量小的表)
ALTER TABLE your_table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
第三步:若字段含 TEXT/BLOB 或已有全文索引,必须单独改列,避免锁表和索引重建风险:
ALTER TABLE your_table_name MODIFY COLUMN content TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
注意:MODIFY 必须重写完整字段定义(包括 NULL/NOT NULL、DEFAULT 等),否则会丢失约束。
验证 INSERT 是否真正生效
用 DB::insert() 执行一条带中文的原始 SQL:
DB::insert("INSERT INTO users (name) VALUES (?)", ['张三']);
如果仍报 General error,立刻检查:① 上一步 SHOW VARIABLES 三个 utf8mb4 是否全齐;② 表字段是否真被 CONVERT TO 或 MODIFY 刷写过;③ DB::connection()->getPdo()->getAttribute(PDO::ATTR_CLIENT_VERSION) 返回的驱动版本是否支持 utf8mb4(PHP 7.4+、MySQLi 8.0+ 推荐)。
这一步成功后,Eloquent 的 $model->save() 和 Model::create() 就不会再因中文触发 General error。











