Статьи

Управление Cronjobs с Laravel

Временами вашему приложению необходимо периодически запускать административные задачи на сервере. Если вы хотите отправить электронное письмо своим пользователям или очистить таблицы базы данных в конце дня, вам понадобится механизм планирования задач, чтобы позаботиться о задачах, когда пришло время.

Cron — это планировщик задач в Unix-подобных системах, который запускает команды оболочки через определенные промежутки времени. Эта статья не предназначена для ознакомления с Cron, но, поскольку она является ключевой концепцией в нашем руководстве, мы опишем основы его работы.

A clock

Основы Cron

Cron — это демон планировщика задач, который запускает запланированные задачи через определенные промежутки времени. Cron использует файл конфигурации crontab, также известный как таблица cron, для управления процессом планирования.

Crontab содержит задания cron, каждое из которых связано с определенной задачей. Задания Cron состоят из двух частей: выражения cron и команды оболочки для запуска:

*   *   *   *   * command / to / run 

Каждое поле в вышеприведенном выражении ( * * * * * ) является опцией для установки частоты расписания. Он состоит из минуты, часа, дня месяца, месяца и дня недели в порядке размещения. Символ звездочки относится ко всем возможным значениям для соответствующего поля. В результате вышеуказанная работа cron будет выполняться каждую минуту в течение дня.

Следующее задание cron выполняется каждый день в 12:30 :

 30   12   *   *   *  command / to / run 

Это только вершина айсберга Крона; чтобы узнать больше об этом, вы можете посетить страницу википедии .

В приложениях на основе PHP административные задачи обычно представляют собой автономные сценарии PHP, которые выполняются в режиме CLI. Эти сценарии написаны для выполнения различных заданий в определенное время.

Тем не менее, мы не можем многое сделать без возможности других библиотек PHP и фреймворков. В этой статье вы узнаете, как использовать инфраструктуру Laravel для создания надежных сценариев PHP для командной строки и планировать их прямо из исходного кода.

Создание команд в Laravel

Создать команду в PHP так же просто, как создать скрипт PHP, а затем запустить его в командной строке с помощью команды php :

 php somefile . php 

Как видите, файл передается в качестве аргумента команде php .

Независимо от того, было ли ваше приложение разработано в Laravel, или вы просто хотите использовать его фасады и помощники для создания ваших сценариев, вам нужно будет загрузить Laravel перед его использованием. Однако есть лучшая альтернатива этому: создание команды Laravel Artisan .

При использовании команд Artisan у нас будет доступ ко всем функциям Laravel, включая помощники, фасады и другие команды Artisan, и это лишь некоторые из них.

Мы не будем вдаваться в подробности команд Artisan, так как они выходят за рамки этого руководства, но давайте обсудим основы, только чтобы начать. Мы будем использовать последнюю версию Laravel, которая на момент написания этой статьи была 5.1 .

Мы используем команду make:console Artisan для генерации каркаса класса команды для работы. В качестве примера, мы собираемся создать команду, которая отправляет SMS-сообщение с днем ​​рождения нашим пользователям в день их рождения.

 $ php artisan make : console HappyBirthday   -- command = sms : birthday 

Приведенная выше команда создаст класс с именем HappyBirthday в файле с тем же именем в каталоге app/Console/Commands . Мы также выбрали имя для команды с помощью параметра command . Это имя, которое мы будем использовать при вызове команды.

Теперь давайте откроем файл и посмотрим, что у нас есть. Внутри класса есть несколько свойств и методов, которые создают бэкэнд команды:

 <? php namespace   App \Console\Commands ; 

 use   Illuminate \Console\Command ; 

 class   HappyBirthday   extends   Command 
 { 
     /** * The name and signature of the console command. * * @var string */ 
     protected  $signature =   'sms:birthday' ; 

     /** * The console command description. * * @var string */ 
     protected  $description =   'Command description.' ; 

     /** * Create a new command instance. * * @return void */ 
     public   function  __construct () 
     { parent :: __construct (); 
     } 

     /** * Execute the console command. * * @return mixed */ 
     public   function  handle () 
     { 
         // 
     } 
 } 

Для $description мы можем поместить простое описание того, что команда делает при выполнении.

 protected  $description =   'Sends a Happy birthday message to users via SMS' ; 

В Laravel 5.1 всякий раз, когда команда выполняется в терминале, вызывается метод handle класса команды. Вот где мы должны поставить нашу логику.

В нашем случае, чтобы отправить сообщение о дне рождения пользователям в день их рождения, мы можем изменить метод handle следующим образом:

 <? php // ... 
 public   function  handle () 
 { 
   User :: whereBirthDate ( date ( 'm/d' ))-> get ();  

   foreach (  $users as  $user )   { 
     if ( $user -> has ( 'cellphone' ))   { SMS :: to ( $user -> cellphone ) 
        -> msg ( 'Dear '   .  $user -> fname .   ', I wish you a happy birthday!' ) 
        -> send (); 
     }    
 } $this -> info ( 'The happy birthday messages were sent successfully!' ); 

 } 

Как только команда закончена, нам нужно зарегистрировать ее в Artisan, чтобы она была доступна в терминале. Для этого нам просто нужно добавить имя класса commands массив commands класса Kernel , который находится в app/Console/Kernel.php :

 <? php class   Kernel   extends   ConsoleKernel 
 { 
     /** * The Artisan commands provided by your application. * * @var array */ 
     protected  $commands =   [ 
         // ... 
         'App\Console\Command\HappyBirthday' 
     ]; 

     // ... 

Если мы запустим php artisan list в терминале, мы увидим описание нашей команды:

 $ php artisan list ... sms sms : birthday Sends  a Happy  birthday to users via SMS ... 

Это хорошая привычка именовать имена команд. Это поможет нам классифицировать их в зависимости от их использования.

В результате, всякий раз, когда мы запускаем команду в терминале, соответствующая группа пользователей будет отправлять сообщение с днем ​​рождения:

 $ php artisan sms : birthday The  happy birthday messages were sent successfully ! 

Это всего лишь гипотетический вариант использования. Для более конкретного примера см. Пост Юнеса Рафи о команде минификации.

Планирование команд

Здесь начинается самое интересное. Давайте наметим задачу для запуска команды, которую мы только что создали. Для этого мы воспользуемся функцией, которая вам непременно понравится: Laravel Task Scheduler.

Задачи определены внутри метода schedule класса Kernel . Мы можем добавить столько команд Artisan, сколько нам нужно, используя метод command .

Наша задача, согласно ее использованию, должна выполняться один раз в день. Таким образом, мы можем использовать метод daily() следующим образом:

 <? php // ... 

 protected   function  schedule ( Schedule  $schedule ) 
 { $schedule -> command ( 'sms:birthday' )-> daily (); 
 } 

Мы можем запланировать все команды прямо из метода schedule . Как указано в документации, мы можем назначать задачи различным частотам. Мы перечислим некоторые из них здесь, но вы можете прочитать документацию, чтобы увидеть полный список и решить, что лучше всего соответствует вашим обстоятельствам.

Для запуска задачи каждый час каждый день:

 <? php $schedule -> command ( 'myTask' ) 
          -> hourly ();   

Чтобы запустить задачу каждый день в полночь:

 <? php $schedule -> command ( 'myTask' ) 
          -> daily ();   

Чтобы запустить задачу каждый день в 9:30:

 <? php $schedule -> command ( 'myTask' ) 
          -> dailyAt ( '09:30' );   

Чтобы запустить задачу каждую неделю:

 <? php $schedule -> command ( 'myTask' ) 
          -> weekly ();   

Чтобы запустить его каждый месяц:

 <? php $schedule -> command ( 'myTask' ) 
          -> monthly ();   

Мы также можем использовать пользовательское расписание cron, например, обычное выражение задания cron:

 $schedule -> command ( 'myTask' ) 
          -> cron ( '* * * * *' ); 

Вышеуказанная задача будет выполняться каждую минуту.

Чтобы увидеть полный список опций, пожалуйста, обратитесь к документации, раздел Параметры расписания частоты .

Laravel также предоставляет набор ограничений расписания, которые можно комбинировать с вышеуказанными методами. Например, мы можем запланировать выполнение задачи еженедельно, но ограничить ее определенным днем ​​и часом.

 <? php $schedule -> command ( 'theTask' ) 
          -> weekly () 
          -> mondays () 
          -> at ( 12 : 30 );   

или

 <? php $schedule -> command ( 'theTask' ) 
          -> weekly () 
          -> sundays ()   

Мы можем пойти дальше и ограничить выполнение задачи определенным условием, используя метод when который принимает замыкание. Задача будет выполнена, только если замыкание вернет true .

 <? php $schedule -> command ( 'table:clean' ) 
           -> daily () 
           -> when ( function ()   { 
              return  SMS :: isWorkingFine (); 
           }); 

Запуск планировщика Laravel

Чтобы запустить сам планировщик, нам нужно добавить только одно задание cron на сервере (с помощью команды crontab -e ), которое выполняет php /path/to/artisan schedule:run каждую минуту в день:

 *   *   *   *   *  php / path / to / artisan schedule : run 1 >>   /dev/ null   2 >& 1 

Обратите внимание, что нам необходимо указать полный путь к команде Artisan нашей установки Laravel.

Чтобы отбросить вывод cron, мы ставим /dev/null 2>&1 в конце выражения cronjob.

Чтобы узнать больше о планировщике, см. Главу « Планирование» в документации.

Вывод

В этом уроке мы использовали команды Laravel Artisan для создания команд терминала. Вместо того, чтобы добавлять много записей заданий cron на сервер для каждой задачи, мы создали только одну, которая выполняется каждую минуту и ​​передает ответственность планировщику задач Laravel.

Используя собственные команды Artisan вместе с планировщиком задач Laravel, мы можем сосредоточиться на создании команд, а Laravel позаботится обо всем остальном. В дополнение к этому, частотами планирования управляют другие члены команды, так как теперь она отслеживается системой контроля версий.

Если у вас есть вопросы или комментарии, пожалуйста, оставьте их ниже, и мы сделаем все возможное, чтобы ответить своевременно.