{{TOC}}
{{DOCVER 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01}}
== Введение ==
Раньше вы могли создавать Cron-записи для каждой запланированной задачи на вашем сервере. Но это могло быстро превратиться в рутину, так как планировщик задач больше не находится в системе контроля версий, и вы должны заходить через SSH на свой сервер, чтобы добавить Cron-записи.
Планировщик команд Laravel позволяет вам гибко и выразительно определить планирование своих команд в самом Laravel. И для этого на вашем сервере необходима только одна Cron-запись. Ваш планировщик задач определён в методе %%schedule()%% файла %%(t)app/Console/Kernel.php%%. Чтобы помочь вам начать, там уже есть простой пример с методом.
=== Запуск планировщика ===
При использовании планировщика вам надо добавить на ваш сервер только одну эту Cron-запись. Если вы не знаете, как добавлять Cron-записи на сервер, то можете использовать такой сервис, как ((https://forge.laravel.com Laravel Forge)), который может управлять Cron-записями для вас:
%%(sh)
* * * * * php /path/to/artisan schedule:run >>/dev/null 2>&1
%%
Этот Cron будет вызывать планировщик команд Laravel каждую минуту. Когда будет выполнена команда %%(sh)schedule:run%%, Laravel обработает ваши запланированные задачи и запустит только те задачи, которые должен.
== Определение планировщика ==
Вы можете определить все свои запланированные задачи в методе %%schedule()%% класса %%(t)App\Console\Kernel%%. Для начала давайте посмотрим на пример планирования задачи. В этом примере мы запланируем замыкание %%Closure%%, которое будет вызываться каждый день в полночь. В %%Closure%% мы выполним запрос БД, чтобы очистить таблицу:
%%
call(function () {
DB::table('recent_users')->delete();
})->daily();
}
}
%%
В дополнение к планированию вызовов %%Closure%% вы можете также запланировать ((/docs/v5/artisan Artisan-команды)) и команды операционной системы. Например, вы можете использовать метод %%command()%%, чтобы запланировать Artisan-команду, используя либо имя команды, либо класс:
%%
$schedule->command('emails:send —force')->daily();
$schedule->command(EmailsCommand::class, ['--force'])->daily();
%%
Команда %%exec()%% может быть использована для обращения к операционной системе:
%%
$schedule->exec('node /home/forge/script.js')->daily();
%%
=== Настройки частоты планировщика ===
Конечно, есть множество вариантов планировщика, которые вы можете назначить на свою задачу:
%%(hvlraw)
Метод |
Описание |
->cron('* * * * *'); | Запускать задачу по пользовательскому расписанию |
->everyMinute(); | Запускать задачу каждую минуту |
->everyFiveMinutes(); | Запускать задачу каждые 5 минут |
->everyTenMinutes(); | Запускать задачу каждые 10 минут |
->everyThirtyMinutes(); | Запускать задачу каждые 30 минут |
->hourly(); | Запускать задачу каждый час |
->hourlyAt(17); | Запускать задачу каждый час в хх:17 минут (для версии 5.3 и выше) |
->daily(); | Запускать задачу каждый день в полночь |
->dailyAt('13:00'); | Запускать задачу каждый день в 13:00 |
->twiceDaily(1, 13); | Запускать задачу каждый день в 1:00 и 13:00 |
->weekly(); | Запускать задачу каждую неделю |
->monthly(); | Запускать задачу каждый месяц |
->monthlyOn(4, '15:00'); | Запускать задачу 4 числа каждого месяца в 15:00 (для версии 5.2 и выше) |
->quarterly(); | Запускать задачу каждые 3 месяца (для версии 5.2 и выше) |
->yearly(); | Запускать задачу каждый год |
->timezone('America/New_York'); | Задать часовой пояс (для версии 5.2 и выше) |
%%
Эти методы могут быть объединены с дополнительными ограничениями для создания ещё более гибкого планировщика, который будет работать только в определённые дни недели. Например, чтобы запланировать команду на еженедельный запуск в понедельник:
%%
// Запуск каждый понедельник в 13:00...
$schedule->call(function () {
//
})->weekly()->mondays()->at('13:00');
%%
%%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51, 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15)
~%%
// Запускать каждый час с 8:00 до 17:00 по будням...
$schedule->command('foo')
->weekdays()
->hourly()
->timezone('America/Chicago')
->between('8:00', '17:00');
~%%
%%
Ниже приведён список дополнительных ограничений в расписании:
%%(hvlraw)
Метод |
Описание |
->weekdays(); | Ограничить задачу рабочими днями |
->sundays(); | Ограничить задачу воскресеньем |
->mondays(); | Ограничить задачу понедельником |
->tuesdays(); | Ограничить задачу вторником |
->wednesdays(); | Ограничить задачу средой |
->thursdays(); | Ограничить задачу четвергом |
->fridays(); | Ограничить задачу пятницей |
->saturdays(); | Ограничить задачу субботой |
->between($start, $end); | Ограничить запуск задачи между временем начала и конца промежутка (для версии 5.3 и выше) |
->when(Closure); | Ограничить задачу на основе успешного теста |
%%
%%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51)
**Ограничение промежутком времени**
Методом %%between()%% можно ограничить выполнение задачи в зависимости от времени дня:
~%%
$schedule->command('reminders:send')
->hourly()
->between('7:00', '22:00');
~%%
А методом %%unlessBetween()%% можно исключить выполнение задачи в указанный период времени:
~%%
$schedule->command('reminders:send')
->hourly()
->unlessBetween('23:00', '4:00');
~%%
%%
**Ограничения успешного теста**
Метод %%when()%% может быть использован, чтобы ограничить выполнение задачи на основании результата успешно пройденного теста. Другими словами, если заданное %%Closure%% возвращает %%(t)true%%, задача будет выполняться до тех пор, пока никакие другие ограничивающие условия не препятствуют её выполнению:
%%
$schedule->command('emails:send')->daily()->when(function () {
return true;
});
%%
%%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15)
Метод %%skip()%% является инверсией метода %%when()%%. Если метод %%skip()%% возвращает %%(t)true%%, запланированная задача не будет запущена:
~%%
$schedule->command('emails:send')->daily()->skip(function () {
return true;
});
~%%
%%
При использовании сцепленного метода %%when()%%, запланированная команда выполнится только при условии, что все %%when()%% возвратят %%(t)true%%.
=== Предотвращение перекрытий задач ===
По умолчанию, запланированные задачи будут запускаться, даже если предыдущий экземпляр задачи всё ещё выполняется. Чтобы предотвратить это, вы можете использовать метод %%withoutOverlapping()%%:
%%
$schedule->command('emails:send')->withoutOverlapping();
%%
В этом примере ((/docs/v5/artisan Artisan-команда)) %%(sh)emails:send%% будет запускаться каждую минуту, если она ещё не запущена. Метод %%withoutOverlapping()%% особенно полезен, если у вас есть задачи, которые изменяются коренным образом во время своего выполнения, что мешает вам предсказывать точно, сколько времени данная задача будет выполняться.
%%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51)
=== Режим обслуживания ===
Запланированные задачи Laravel не будут запускаться, когда Laravel находится в ((//docs/v5/configuration#режим режиме обслуживания)), так как мы не хотим, чтобы ваши команды столкнулись с какими-либо незаконченными операциями обслуживания сервера. Но если вы хотите, чтобы задача запускалась даже в режиме обслуживания, вы можете использовать метод %%evenInMaintenanceMode()%%:
~%%
$schedule->command('emails:send')->evenInMaintenanceMode();
~%%
%%
== Выходные данные задачи ==
Планировщик Laravel предоставляет несколько удобных методов для работы с выходными данными, сгенерированными запланированными задачами. Во-первых, используя метод %%sendOutputTo()%%, вы можете отправить вывод данных в файл для последующего анализа:
%%
$schedule->command('emails:send')
->daily()
->sendOutputTo($filePath);
%%
Если вы хотите добавить вывод в указанный файл, вы можете использовать метод %%appendOutputTo()%%:
%%
$schedule->command('emails:send')
->daily()
->appendOutputTo($filePath);
%%
Используя метод %%emailOutputTo()%%, вы можете отправить по электронной почте выходные данные на адрес по вашему усмотрению. Обратите внимание, что данные должны быть сначала отправлены в файл с помощью метода %%sendOutputTo()%%. Перед отправкой на электронную почту результата выполнения задачи вы должны настроить ((/docs/v5/mail службы электронной почты Laravel)):
%%
$schedule->command('foo')
->daily()
->sendOutputTo($filePath)
->emailOutputTo('foo@example.com');
%%
.(alert)
Методы %%emailOutputTo()%%, %%sendOutputTo()%% и %%appendOutputTo()%% доступны исключительно для метода %%command()%% и не поддерживаются для %%call()%%.
== Обработчики прерываний задач ==
Используя методы %%before()%% и %%after()%%, вы можете указать код, который будет выполняться до запуска и после завершения запланированной задачи:
%%
$schedule->command('emails:send')
->daily()
->before(function () {
// Перед запуском задачи...
})
->after(function () {
// Задача завершена...
});
%%
**Пинг URL-адресов**
Используя методы %%pingBefore()%% и %%thenPing()%%, планировщик может автоматически пинговать заданный URL до запуска и после завершения задачи. Этот метод полезен для уведомления внешней службы, например, ((https://envoyer.io Laravel Envoyer)), о том, что ваша запланированная задача запустилась или закончила выполнение:
%%
$schedule->command('emails:send')
->daily()
->pingBefore($url)
->thenPing($url);
%%
Использование функций %%pingBefore($url)%% или %%thenPing($url)%% требует библиотеки Guzzle HTTP.
%%(DOCNEW 5.3=c06d6a2352ed8c767633aab9c20f2bf7d880c967 28.01.2017 5:00:51)
Вы можете добавить Guzzle к вашему проекту с помощью менеджера пакетов Composer:
%%(sh)
composer require guzzlehttp/guzzle
~%%
%%
%%(DOCNEW 5.2=6b0b057ae6de3c88cb29188459e38383c622ec23 8.12.2016 23:00:15, 5.1=cdc24ba7426c5b11eb4d050706bd78c3ea4913cc 19.06.2016 20:08:01)
Вы можете добавить Guzzle к вашему проекту, добавив следующую строку в файл %%(t)composer.json%%:
%%(t)
"guzzlehttp/guzzle": "~5.3|~6.0"
~%%
%%