Laravel 8 类结构
任务类非常简单,通常只包含一个 handle
方法,在队列处理任务时将会调用它。让我们从一个任务类的例子看起。在这个例子中,我们假设我们管理一个 podcast 服务,并且需要在上传的 podcast 文件发布之前对其进行处理:
<?php
namespace App\Jobs;
use App\Models\Podcast;
use App\Services\AudioProcessor;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
class ProcessPodcast implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
protected $podcast;
/**
* 创建一个新的任务实例。
*
* @param Podcast $podcast
* @return void
*/
public function __construct(Podcast $podcast)
{
$this->podcast = $podcast;
}
/**
* 运行任务
*
* @param AudioProcessor $processor
* @return void
*/
public function handle(AudioProcessor $processor)
{
// Process uploaded podcast...
}
}
在本例中,请注意我们能够将一个 Eloquent model 直接传递到已排队任务的构造函数中。由于任务所使用的 SerializesModels
,在任务处理时,Eloquent 模型及其加载的关系将被优雅地序列化和非序列化。如果你的队列任务在其构造函数中接受一个 Eloquent 模型,那么只有模型的标识符才会被序列化到队列中。当实际处理任务时,队列系统将自动重新从数据库中获取完整的模型实例及其加载的关系。它对你的应用程序来说是完全透明的,并且可以防止在序列化完整的 Eloquent 模型实例时可能出现的问题。
当任务由队列处理时,将调用 handle
方法。注意,我们可以对任务的 handle
方法进行类型提示依赖。Laravel 服务容器 会自动注入这些依赖项。
如果您想完全控制容器如何将依赖注入 handle
方法,你可以使用容器的 bindMethod
方法。bindMethod
方法接受一个回调,该回调接收任务和容器。在回调中,你可以随意调用 handle
方法。通常,您应该从服务提供者中调用此方法:
use App\Jobs\ProcessPodcast;
$this->app->bindMethod(ProcessPodcast::class.'@handle', function ($job, $app) {
return $job->handle($app->make(AudioProcessor::class));
});
注意:二进制数据,例如原始图像内容,应该在传递到队列任务之前通过
base64_encode
函数传递。否则,在将任务放入队列时,可能无法正确地序列化为 JSON。