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

时间:2015-07-23 22:48:27

标签: php laravel cron laravel-5 laravel-5.1

我想知道将周末等事情添加到可用的时间表限制中的最佳方法是什么:

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

和它的逻辑相反:

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

我会将这些内容包含在哪里,以免被框架更新覆盖?

2 个答案:

答案 0 :(得分:1)

首先,如果您缺少的是 weekendnds()方法,则可以通过在活动中调用天(6,7)来实现此目的。< / p>

如果您需要为调度程序添加更多逻辑,请继续阅读。

我查看了代码,而Laravel没有提供扩展调度程序的方法,特别是其预定的事件,还有其他方法,它仍然是可以从 Kernel :: schedule()中应用其他约束。

根据您的需要,有两种方法可以做到。

  1. 如果要为事件设置一些自定义CRON表达式,只需使用 cron()方法:

    protected function schedule(Schedule $schedule)
    {
        $schedule->call(function () {
            //scheduled code
        })->cron('0 1 2 * * *')->daily();
    }
    
  2. 如果您需要使用现有方法应用某些CRON约束,但需要稍后以工作日()使用 spliceIntoPosition 的方式进行修改,则可以访问通过调用 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
    }
    
  3. 如果要为多个事件重用逻辑,可以在 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中,您还需要确保新的计划类用于计划:

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

答案 1 :(得分:0)

遵循@ jedrzej.kurylo的回答,我在laravel 5.8上这样做:

php artisan make:model CustomCallbackEvent

php artisan make:model CustomEvent

php artisan make:model CustomSchedule

在CustomCallbackEvent中:

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);
    }
}

在CustomSchedule中:

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;
    }
}

在CustomEvent中:

use Illuminate\Console\Scheduling\Event;

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

在Kernel.php中:

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

      $this->schedule($schedule);
    }