向Laravel 5调度程序添加自定义方法

nbysray5  于 2022-12-14  发布在  其他
关注(0)|答案(3)|浏览(170)

我想知道什么是最好的方法来添加像周末这样的事情到可用的时间表限制:

Illuminate\Console\Scheduling\Event.php
public function weekdays()
{
    return $this->spliceIntoPosition(5, '1-5');
}

和它的逻辑相反:

public function weekends()
{
        return $this->days(array( '0','6'));
}

我应该在哪里包含这些内容,以便它们不会被框架更新覆盖?

axr492tv

axr492tv1#

首先,如果缺少的只是weekends()方法,则可以通过在事件上调用days(6,7)来实现。
如果您需要向调度程序添加更多的逻辑,请继续阅读。
我看了一下代码,虽然Laravel没有提供扩展
Scheduler
的方法,特别是它的调度Events,但仍然可以从**Kernel::schedule()应用其他约束。
根据您的需要,有两种方法可以实现。
1.如果你想为一个事件设置一些自定义的CRON表达式,你可以简单地使用它的
cron()**方法:

protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        //scheduled code
    })->cron('0 1 2 * * *')->daily();
}

1.如果您需要使用现有方法应用某些CRON约束,但需要稍后使用spliceIntoPosition以**weekdays()的方式修改它,则可以通过调用getExpression()访问它,修改它,然后使用cron()**进行设置。

protected function schedule(Schedule $schedule)
{
    $event = $schedule->call(function () {
        //scheduled code
    });

    $scheduledAt = $event->getExpression(); //get cron expression

    ...; //modify the $scheduledAt expression

    $event->cron($scheduledAt); // set the new schedule for that even
}

如果你想为多个事件重用逻辑,你可以在你的Kernel.php中添加帮助函数,例如:

protected function specialSchedule(\Illuminate\Console\Scheduling\Event $event) {
      $scheduledAt = $event->getExpression();

      ...; // modify $scheduledAt expression

      $event->cron($scheduledAt);

      return $event;
    }

然后,您可以在定义排程时重复使用该逻辑:

protected function schedule(Schedule $schedule)
    {
        $this->specialSchedule($schedule->call(function () {
            //scheduled code
        }));
    }

更新日期:

还有一种方法可以做到这一点--有点复杂,因为它要求您提供自己的Schedule和Event类,但也更加灵活。
首先,实现您自己的Event类并在其中添加新方法:

class CustomEvent extends \Illuminate\Console\Scheduling\CallbackEvent {
      public function weekends() {
        return $this->days(6,7);
      }
    }

然后是您自己的Schedule类,以便它创建CustomEvent对象:

class CustomSchedule extends \Illuminate\Console\Scheduling\Schedule 
    {
      public function call($callback, array $parameters = [])
      {
        $this->events[] = $event = new CustomEvent($callback, $parameters);

         return $event;
      }

      public function exec($command, array $parameters = [])
      {
        if (count($parameters)) {
          $command .= ' '.$this->compileParameters($parameters);
        }

        $this->events[] = $event = new Event($command);

        return $event;
      }
   }

最后,在你的Kernel.php中,你还需要确保你的新schedule类被用于调度:

protected function defineConsoleSchedule()
    {
      $this->app->instance(
        'Illuminate\Console\Scheduling\Schedule', $schedule = new Schedule
      );

      $this->schedule($schedule);
    }
lztngnrs

lztngnrs2#

根据jedrzej.kurylo的回答,我在laravel 5.8上做了以下操作:
php artisan make:model CustomCallbackEvent
php artisan make:model CustomEvent
php artisan make:model CustomSchedule
在自定义回调事件中:

use Illuminate\Console\Scheduling\CallbackEvent;
use Illuminate\Console\Scheduling\EventMutex;

class CustomCallbackEvent extends CallbackEvent
{
    public function __construct(EventMutex $mutex, $callback, array $parameters = [])
    {
        parent::__construct($mutex, $callback, $parameters);
    }
}

在自订排程中:

use Illuminate\Console\Scheduling\Schedule;

class CustomSchedule extends Schedule
{
    public function call($callback, array $parameters = [])
    {
        $this->events[] = $event = new CustomCallbackEvent(
            $this->eventMutex,
            $callback,
            $parameters
        );

        return $event;
    }

    public function exec($command, array $parameters = [])
    {
        if (count($parameters)) {
            $command .= ' '.$this->compileParameters($parameters);
        }

        $this->events[] = $event = new CustomEvent($this->eventMutex, $command, $this->timezone);

        return $event;
    }
}

在自定义事件中:

use Illuminate\Console\Scheduling\Event;

class CustomEvent extends Event
{
    public function myFunction()
    {
        //your logic here
    }
}

在内核.php中:

protected function defineConsoleSchedule()
    {
      $this->app->instance(
        'Illuminate\Console\Scheduling\Schedule', $schedule = new CustomSchedule
      );

      $this->schedule($schedule);
    }
li9yvcax

li9yvcax3#

Illuminate\Console\Scheduling\Event类使用Macroable特征,这意味着你可以动态地向类中添加方法,而不需要继承它。
首先,你必须注册它在 Boot 方法:

use Illuminate\Console\Scheduling\Event;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    public function boot()
    {
        Event::macro(
            'weekends',
            function () {
                /** @var Event $this */
                return $this->days([0, 6]);
            }
        );
    }
}

然后,您可以将其用作任何其他方法:

$schedule->command('do-work')->weekends();

有关宏的详细信息,请参阅https://asklagbox.com/blog/laravel-macros

相关问题