请参阅 安装指南 以获取有关如何设置调度任务的说明。
过去,开发者会为每个需要调度的任务生成一个 Cron 条目。然而,这有时会是一个令人头疼的问题。你的任务调度不再处于版本控制中,并且你必须通过 SSH 连接到服务器来添加 Cron 条目。命令调度器允许你在应用程序本身中流畅而富有表现力地定义你的命令调度,并且你的服务器上只需要一个 Cron 条目。
您可以通过覆盖 插件注册文件 中的 registerSchedule 方法来定义所有定时任务。该方法将接受一个 $schedule 参数,并用于定义命令及其执行频率。
首先,我们来看一个调度任务的例子。在这个例子中,我们将调度一个 Closure,使其每天午夜被调用。在 Closure 中,我们将执行一个数据库查询来清空一个表:
class Plugin extends PluginBase
{
// ...
public function registerSchedule($schedule)
{
$schedule->call(function () {
Db::table('recent_users')->delete();
})->daily();
}
}除了调度 Closure 调用之外,您还可以调度 控制台命令 和操作系统命令。例如,您可以使用 command 方法来调度一个控制台命令:
$schedule->command('cache:clear')->daily();该 exec 命令可用于向操作系统发出命令:
$schedule->exec('node /home/acme/script.js')->daily();当然,有多种排程您可以分配给您的任务:
| Method | Description |
|---|---|
->cron('* * * * *'); | Run the task on a custom Cron schedule |
->everyMinute(); | Run the task every minute |
->everyFiveMinutes(); | Run the task every five minutes |
->everyTenMinutes(); | Run the task every ten minutes |
->everyThirtyMinutes(); | Run the task every thirty minutes |
->hourly(); | Run the task every hour |
->daily(); | Run the task every day at midnight |
->dailyAt('13:00'); | Run the task every day at 13:00 |
->twiceDaily(1, 13); | Run the task daily at 1:00 & 13:00 |
->weekly(); | Run the task every week |
->monthly(); | Run the task every month |
这些方法可以与额外的约束结合,以创建更加精细的调度,使其只在每周的特定几天运行。例如,要调度一个命令使其每周一运行:
$schedule->call(function () {
// Runs once a week on Monday at 13:00...
})->weekly()->mondays()->at('13:00');以下是附加的进度约束列表:
| Method | Description |
|---|---|
->weekdays(); | Limit the task to weekdays |
->sundays(); | Limit the task to Sunday |
->mondays(); | Limit the task to Monday |
->tuesdays(); | Limit the task to Tuesday |
->wednesdays(); | Limit the task to Wednesday |
->thursdays(); | Limit the task to Thursday |
->fridays(); | Limit the task to Friday |
->saturdays(); | Limit the task to Saturday |
->when(Closure); | Limit the task based on a truth test |
when 方法可用于根据给定真值测试的结果来限制任务的执行。换句话说,如果给定的 Closure 返回 true,任务将执行,只要没有其他限制条件阻止任务运行:
$schedule->command('emails:send')->daily()->when(function () {
return true;
});默认情况下,即使该任务的先前实例仍在运行,计划任务也会继续运行。为了防止这种情况,你可以使用 withoutOverlapping 方法:
$schedule->command('emails:send')->withoutOverlapping();在此示例中,emails:send 控制台命令将每分钟运行一次,如果它尚未运行。withoutOverlapping 方法在您有执行时间差异很大的任务时特别有用,从而避免您需要精确预测给定任务将花费多长时间。
调度器提供了几种便捷的方法,用于处理定时任务生成的输出。首先,使用 sendOutputTo 方法,你可以将输出发送到一个文件,以便后续检查。
$schedule->command('emails:send')
->daily()
->sendOutputTo($filePath);使用 emailOutputTo 方法,您可以将输出通过电子邮件发送到您选择的电子邮件地址。请注意,输出必须首先使用 sendOutputTo 方法发送到一个文件。此外,在通过电子邮件发送任务输出之前,您应该配置邮件服务。
$schedule->command('foo')
->daily()
->sendOutputTo($filePath)
->emailOutputTo('foo@example.tld');
emailOutputTo和sendOutputTo方法仅适用于command方法,不适用于call。
使用 before 和 after 方法,你可以指定要在计划任务完成前后执行的代码:
$schedule->command('emails:send')
->daily()
->before(function () {
// Task is about to start...
})
->after(function () {
// Task is complete...
});使用 pingBefore 和 thenPing 方法, 调度器可以自动在任务完成之前或之后 ping 指定的 URL。 此方法有助于通知外部服务, 您的计划任务正在开始或已完成:
$schedule->command('emails:send')
->daily()
->pingBefore($url)
->thenPing($url);