必须在连接层、迁移层、服务端三处同步启用utf8mb4:改config/database.php的charset/collation/options;在appserviceprovider中设schema::defaultstringlength(191);mysql配置文件添加character-set-server和collation-server并重启。

让Laravel项目从初始化就支持emoji和中文生僻字,避免存入数据库变???或直接报错SQLSTATE[HY000]: General error: 1366 Incorrect string value,必须在连接层、迁移层、服务端三处同步启用utf8mb4,漏掉任意一环都会导致乱码。
第一步:改 Laravel 连接层配置
打开 config/database.php,找到 mysql 配置块,在其中添加或修改三项:
【charset => 'utf8mb4',
【collation => 'utf8mb4_unicode_ci',
【options => [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"]
别只改 .env 里的 DB_CHARSET=utf8mb4——这个变量 Laravel 官方根本不读,纯属误导。
第二步:强制统一迁移字符串长度
在 app/Providers/AppServiceProvider.php 的 boot() 方法里,插入这一行:
Schema::defaultStringLength(191);
这一步必须做。Laravel 9.x 之前默认用 utf8 建表,即使你上面配对了,php artisan migrate 生成的表仍是 utf8 编码,emoji 一存就丢。
第三步:MySQL 服务端确认并重启
编辑 MySQL 配置文件:
Linux 是 /etc/mysql/my.cnf,Windows 是 my.ini;
在 [mysqld] 段落下添加两行:
character-set-server = utf8mb4<br>collation-server = utf8mb4_unicode_ci
保存后重启 MySQL 服务,然后执行:mysql -u root -p -e "SHOW VARIABLES LIKE 'character_set%';"
确认 character_set_server 和 character_set_database 都是 utf8mb4。
第四步:已有库表手动升级(仅需一次)
方法一:进 MySQL 命令行,逐个执行:
ALTER DATABASE your_db_name CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
方法二:用 Laravel 执行(替换 users 为你的表名):
DB::statement("ALTER TABLE users CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci");
注意:只改表默认字符集不够,旧字段仍为 utf8,必须用 CONVERT TO 全量重写字段编码。
第五步:新建迁移文件显式声明字符集
写迁移时不要只写 $table->string('title'),要追加 ->charset('utf8mb4') 或 ->collation('utf8mb4_unicode_ci'):
① 第一步:运行 php artisan make:migration create_posts_table
② 第二步:在 up() 方法中写:
$table->string('title')->charset('utf8mb4');<br>$table->text('content')->collation('utf8mb4_unicode_ci');
③ 第三步:运行 php artisan migrate —— 此时新表才会真正用 utf8mb4 创建。











