Laravel如何在执行前后调用作业类的方法

Non*_*llt 3 php laravel laravel-5.4

我在使用 Laravel 队列时遇到问题。由于我正在使用可扩展架构,因此我所做的大多数事情都是使用队列和作业来实现的。例如,在处理大文件时,为文件中的每 1000 行创建一个作业,并将结果保存到输出文件中。

我有一个“Process”类,我目前正在将其用作作业的父级。process 类具有 start() 和 end() 方法,应在调用 job handler() 方法后以及执行该方法后调用这些方法。当前的解决方案是从handle方法调用这些方法,但问题是这种解决方案增加了作业类本身不必要的代码,并且需要实现者记住调用这些方法。

public function handle()
{
    $this->start(); // <- implementer has to remember to call this

    // Do the actual handle functionality

    $this->end(); // <- and this
}
Run Code Online (Sandbox Code Playgroud)

所以我想知道是否有一种“干净”的方法可以做到这一点,不需要从作业(子)类调用父方法?我尝试使用队列事件,但无法从给定的事件对象构造作业类。从作业中分派事件并没有真正的帮助,因为您仍然需要在每个作业类中添加这两行额外的行。

除了 Laravel 特定的实现之外,我还研究了神奇的 __call() 方法,但这只有在“handle”方法不存在时才有效,考虑到 artisan make:job 命令通过以下方式生成该方法,这并不是真正的最佳选择默认值(再次要求实现者足够精明才能删除它)。

需要明确的是,当前的解决方案确实有效,但为每个类复制相同的行似乎有代码味道。

小智 6

您可以创建一个具有句柄函数的父类,他将在具有您的逻辑的子类中调用受保护的函数,例如:

class MyJob implements ShouldQueue
{
    use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;

    protected function start() {
        // your start logic
    }

    protected function stop() {
        // your stop logic
    }

    protected function process() {
        // will be overrittten
    }

    public function handle() {
        $this->start();
        $this->process();
        $this->stop();
    }
}
Run Code Online (Sandbox Code Playgroud)

你所有的工作都会扩展你的课程,例如:

class SpecificJob extends MyJob
{
    protected function process() {
         // logic
    }
}
Run Code Online (Sandbox Code Playgroud)