根本原因是序列化过程中字符编码未被正确保留,尤其在linux服务器locale非utf-8时触发;需检查并设置系统locale为utf-8,修改queue_jobs表payload字段为utf8mb4,并重写job的__serialize/__unserialize方法强制utf-8转码。

在Laravel中使用Redis或Database驱动运行队列任务时,中文参数传入Job构造函数后,在handle方法里变成乱码或空字符串,根本原因是序列化过程中字符编码未被正确保留,尤其在Linux服务器上默认locale非UTF-8时极易触发。
确认当前环境locale编码
SSH登录服务器,执行locale命令,检查LANG和LC_ALL是否为en_US.UTF-8或zh_CN.UTF-8;若显示POSIX或不含UTF-8,问题已定位。
临时修复:执行export LC_ALL=en_US.UTF-8,但该设置仅对当前会话生效。
永久设置系统级UTF-8 locale
编辑/etc/default/locale文件,写入以下两行:
LANG="en_US.UTF-8"
LC_ALL="en_US.UTF-8"
若该文件不存在,直接创建;修改后必须重启supervisor或systemd管理的队列进程,否则新locale不会加载到worker进程中。
强制Job类使用UTF-8序列化
方法一:在Job类的__construct()中对所有字符串参数显式转码
public function __construct(string $title, string $content) {
$this->title = mb_convert_encoding($title, 'UTF-8', 'auto');
$this->content = mb_convert_encoding($content, 'UTF-8', 'auto');
}
方法二:重写Job的__serialize()和__unserialize()方法(Laravel 9+支持)
在Job类中添加:
public function __serialize(): array {
return array_map(function ($val) {
return is_string($val) ? mb_convert_encoding($val, 'UTF-8', 'auto') : $val;
}, get_object_vars($this));
}
public function __unserialize(array $data): void {
foreach ($data as $key => $value) {
$this->$key = $value;
}
}
数据库驱动下修复queue_jobs表字段编码
第一步:检查queue_jobs表的payload字段字符集
执行SQL:SHOW CREATE TABLE queue_jobs;,确认payload字段是否为utf8mb4类型;若显示utf8或latin1,立即修复。
第二步:修改字段字符集与排序规则
执行:ALTER TABLE queue_jobs MODIFY payload LONGTEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
第三步:同步更新failed_jobs表(如有)
ALTER TABLE failed_jobs MODIFY payload TEXT CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
【必须执行DB::statement()刷新连接】修改后,在Artisan命令中运行php artisan queue:restart,否则新连接仍可能使用旧连接池缓存的字符集配置。











