必须打通php到mysql全链路utf8mb4支持,包括mysql服务端配置、laravel数据库连接设置、现有表结构升级、迁移索引长度限制及windows下artisan中文显示修复。

在Laravel项目中存入中文标题、用户昵称或Emoji表情时,数据库报错SQLSTATE[HY000]: General error: 1366 Incorrect string value,或字段内容变成???,说明字符集配置存在断裂——仅改数据库或仅改Laravel配置都不够,必须打通从PHP连接层到MySQL服务端的全链路utf8mb4支持。
确认MySQL服务端已启用utf8mb4
登录MySQL命令行,执行:SHOW VARIABLES LIKE 'character_set%'; 和 SHOW VARIABLES LIKE 'collation%';。重点检查character_set_server和collation_server是否为utf8mb4与utf8mb4_unicode_ci。若不是,需修改MySQL配置文件(如/etc/mysql/my.cnf或C:\ProgramData\MySQL\MySQL Server X.X\my.ini),在[mysqld]段下添加:
character-set-server = utf8mb4collation-server = utf8mb4_unicode_ci
【必须重启MySQL服务才能生效】。不重启,所有后续配置都只是空中楼阁。
修改Laravel数据库连接配置
打开config/database.php,定位到'mysql'配置块,确保包含以下四项:
'charset' => 'utf8mb4','collation' => 'utf8mb4_unicode_ci','prefix' => '','options' => [PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8mb4 COLLATE utf8mb4_unicode_ci"],
注意:DB_CHARSET=utf8mb4写在.env里是无效的——Laravel官方配置未读取该变量,删掉它,避免误导。
升级现有数据库与表结构
方法一:一次性升级整个数据库
执行SQL:ALTER DATABASE `your_database_name` CHARACTER SET = utf8mb4 COLLATE = utf8mb4_unicode_ci;
方法二:逐表转换(推荐用于生产环境)
① 先转换表字符集:ALTER TABLE `users` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
② 再单独修正可能过长的字段(如email、name等带索引的VARCHAR字段):ALTER TABLE `users` CHANGE `email` `email` VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
③ 检查并重建索引,避免Specified key was too long错误。
这一步不能跳过。哪怕Laravel连接设对了,旧表仍是utf8编码,插入emoji仍会失败。
修复Laravel迁移文件中的索引长度限制
在app/Providers/AppServiceProvider.php的boot()方法中加入:
use Illuminate\Support\Facades\Schema;Schema::defaultStringLength(191);
此设置让后续所有string()字段默认长度为191而非255,适配utf8mb4下InnoDB索引最大长度限制(767字节 ÷ 4字节/字符 ≈ 191字符)。新项目建议直接加,老项目若已存在迁移,需手动调整字段长度再重跑。
验证Artisan命令行中文显示
仅Windows系统需处理:打开项目根目录下的artisan文件,在#!/usr/bin/env php下方插入:
if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') { exec('chcp 65001 > nul'); }
保存后关闭当前终端,新开一个CMD或PowerShell窗口再运行php artisan tinker,输入中文字符串测试输出是否正常。Linux/macOS无需此步。











