如何在 laravel 5.8 中的特定日期和时间执行命令?

How I can execute a command at a specific date and time in laravel 5.8?

Ι 需要能够在特定日期和时间将命令安排到 运行。

我有以下世界末日核武器命令:

<?php

namespace App\Console\Commands;

class DommdayCommand extends Command
{

  protected $signature='nuke:country {commander} {country} ';
  protected $description="Nuke a country";

  public function handle()
  {
    $dictator= $this->argument('commander');
    $country= $this->argument('country');

    $this->output("Nuking the {$country} from {$dictator} ");
  }
}

我有一个具体的时间表:

Kim Young Un will nuke Amerika at 2021-06-12 13:00
Osama Bin laden's clone will nuke Amerika at 2021-06-15 18:00
Adolf Hitler's clone will nuke Israel at 2021-06-15 06:00
...

那么我如何编写特定于日期的计划,在特定日期和时间仅执行一次特定命令?现有的 documentation 允许我安排一个在特定日期和时间连续执行的命令,例如每小时或每天。

那么我如何指定将执行的具体日期。

现有的cron()函数允许我控制在小时、分钟、月、日和星期几的执行。但它不允许我指定执行年份。就我而言,执行年份也很重要。 (我们不想让一个特定的指挥官对一个已经拥有核武器的国家重新发动核攻击,该指挥官在明年也使用核武器也不可行)。

例如,如果我在 Kernel.php 中指定以下内容:

  $schedule->command(DommdayCommand::class)->cron('13 00 15 02 *')

将在 2021-02-15 13:00 处执行命令,但也会在 2022-02-15 13:00 处执行命令 我不想这样做。我只想在 2021-02-15 13:00 被执行,永远不会再被执行。

根据documentation你可以使用cron来检查:

  • 小时
  • 分钟

根据控制台命令执行。虽然它可能会导致 运行 您在 cron 上指定的每个月的日期小时和分钟,但您可以调用闭包,如 documentation 中所见。因此,您可以在 Kernel.php.

处使用年度检查的闭包
use Carbon\Carbon;
use Illuminate\Support\Facades\Artisan


class Kernel extends ConsoleKernel
{
  
  // Some code exists here
  
  protected function schedule(Schedule $schedule): void
  {

      // Rest of schedules

       $schedule->call(function () {
               $year = Carbon::now()->y;
               if($year == 2021){
                  Artisan::call('nuke:country "Kim Young Un" Amerika');
                }
        })->cron('13 00 12 06 *');


      // More schedules

  }

  // Rest of code here
}

因此,使用闭包检查年份,如果年份合适,则调用代码,同时在 cron 表达式上检查执行的月、日、小时和分钟。

另一种方法是让闭包处理所有事情:

$schedule->call(function () {

  $dates=[
    '2021-06-12 13:00' => [
       'commander'=>'Kim Young Un',
       'country'  => 'America'
     ],
     '2021-06-15 18:00' => [
       'commander'=>'Osama Bin Laden's clone',
       'country'  => 'America'
     ],
     '2021-06-15 06:00' => [
       'commander'=>'Adolf Hitler's clone',
       'country'  => 'Israel'
     ],
  ];  

  $date = Carbon::now()->format('Y-m-d H:i:s');
  
  if(isset($dates[$date])){
     $params=$dates[$date];
     Artisan::call("nuke:country \"{$params['commander']}\" {$params['country']}");
  }
})->cron('*****');

换句话说,在适当的日期执行命令,并不断检查执行日期是否合适。