您如何处理 laravel 队列中的 class 名称更改?

How can you handle class name changes in laravel queues?

当我排队 laravel 可邮寄以在 15 分钟后执行时,如下所示:

Mail::to($user)->later(now()->addMinutes(15), new EmailConfirm($user));

Laravel 将 EmailConfrim class 存储在 jobs table.

payload 列中

如果我发布一个将 class 名称 EmailConfirm 更改为 ConfirmEmail 的版本,我将在 15 分钟后执行代码时收到以下错误:

prod.ERROR: Illuminate\Mail\SendQueuedMailable::handle(): The script 
tried to execute a method or access a property of an incomplete object.
Please ensure that the class definition 
"App\Mail\Mailables\EmailConfrim" of the object you are trying to
operate on was loaded _before_ unserialize() gets called or provide an 
autoloader to load the class definition

此错误告诉我负载中定义的 class 不再存在。

我一直在尝试的一个解决方案是将 app_version_number 添加到 laravel 生成的 jobs table。然后我不会让我的 laravel 工人死去,直到在 运行:

之前为该版本执行所有作业

php artisan queue:restart.

这将花费我一些时间来可靠地编写代码,因为它将特定于我们的生产环境。我怎样才能以更 eloquent 的方式解决这个问题?

我会暂时将 both 类 留在代码库中,部署它,然后 15 分钟(或任何工作逗留的最长时间)稍后推送 删除 旧的。

这个答案非常类似于 但是 我建议通过扩展维护 EmailConfirm 以避免在您的队列赶上时进行双重维护:

class EmailConfirm extends ConfirmEmail
{
    // This is just a shell/alias/wrapper/whatever for the real class
}

class ConfirmEmail
{
    function __construct( $param )
    {
        // Maintain this class
    }
}

15 分钟的等待时间还算不错,但是如果您的队列几天都排不上来,您需要多次更换 ConfirmEmail 怎么办?