必须为每个数据库连接单独指定charset和collation,不能复用默认配置;在config/database.php的connections数组中,mysql_secondary等连接需显式声明'charset' => 'utf8'、'collation' => 'utf8_unicode_ci'等参数,否则会因编码不匹配导致sqlstate[hy000]: general error: 1366错误。

当 Laravel 项目中配置了多个 MySQL 数据库连接,而主库用 utf8mb4、副库仍为旧版 utf8 时,直接复用默认 charset 配置会导致中文插入失败或报错 SQLSTATE[HY000]: General error: 1366 Incorrect string value——必须为每个连接单独指定字符集与排序规则,不能共用 config/database.php 中 mysql 块的 charset 设置。
在 connections 数组里为每个连接显式声明 charset 和 collation
打开 config/database.php,定位到 'connections' 数组。不要只复制 mysql 块后仅改 host 和 database,【charset 和 collation 必须各自独立填写】。比如 mysql_secondary 连接若对应的是老版本 MySQL(5.6 或更早),就得把 'charset' => 'utf8'、'collation' => 'utf8_unicode_ci' 显式写进去;而主库保持 'charset' => 'utf8mb4'、'collation' => 'utf8mb4_unicode_ci'。
漏掉这一项,Laravel 会 fallback 到 driver 默认值,MySQL 5.7+ 默认 utf8mb4,但很多遗留库仍是 utf8,不声明就会连错编码层。
环境变量隔离:不同库用不同 charset 环境变量
方法一:在 .env 中为每个连接定义独立 charset 变量,例如:
DB_CHARSET=utf8mb4
DB_COLLATION=utf8mb4_unicode_ci
DB_SECONDARY_CHARSET=utf8
DB_SECONDARY_COLLATION=utf8_unicode_ci
然后在 config/database.php 的对应连接里引用:
'charset' => env('DB_SECONDARY_CHARSET', 'utf8'),
'collation' => env('DB_SECONDARY_COLLATION', 'utf8_unicode_ci')
方法二:不设环境变量,直接硬编码 charset。仅限开发环境或固定部署场景——【线上环境严禁硬编码 charset,否则无法随库版本升级动态调整】。
验证 charset 是否生效的三步检查法
第一步:执行 php artisan tinker,运行 DB::connection('mysql_secondary')->getPdo()->getAttribute(PDO::ATTR_CLIENT_VERSION) → 确认连接已建立且指向目标实例。
第二步:运行 DB::connection('mysql_secondary')->select('SELECT @@character_set_database, @@collation_database') → 查看返回值是否匹配你在 config 中设置的 charset 和 collation。
第三步:插入含 emoji 或生僻中文的测试数据,如 DB::connection('mysql_secondary')->table('test')->insert(['name' => '??测试']); 成功则说明 charset 层级无阻塞。
如果第二步返回 utf8mb4 而你配的是 utf8,说明配置未加载——立刻执行 php artisan config:clear 清缓存,再试。











