Programar tareas en Laravel sin editar crontab (y II)

En el capítulo anterior hablé sobre cómo programar tareas en Laravel sin editar el crontab. Se quedaron algunas cosas en el tintero así que vamos a verlas en esta nueva entrega.

Opciones para la frecuencia de ejecución

En el capítulo anterior vimos dos de las opciones para establecer tareas:

  • dayly() para ejecutar una tarea cada día.
  • hourly() para ejecutar una tarea cada hora.

Aparte de estas dos tenemos otro montón de métodos, por ejemplo:

Cron

Este es el método más flexible y genérico. Usa el mismo formato que las tareas que se definen en un crontab.

Recuerda que el formato de un cron es el siguiente:

minuto hora día mes día_de_la_semana año

Por ejemplo, para ejecutar una tarea todos los días a las 12:00:

->cron(0, 12, *, *, 1, *);

O cada tres minutos:

->cron(*/3, *,  *, *, *, *); // */3 cada tres minutos

O de lunes a viernes a las 14:00:

->cron(0, 14, *, *, 1-5, *); // 1-5 → de lunes a viernes

Nota:

  • Los números van del 0 al 6, siendo el domingo el cero. Si ponemos un 7 también se entenderá que es domingo.

Para facilitarnos el trabajo (y que se entienda el código más fácilmente de un simple vistazo) en Laravel disponemos de una serie de métodos con algunas de las frecuencias más habituales. Por ejemplo:

->dayly()

es evidente lo que hace, de un simple vistazo sabemos que la tarea se ejecuta diariamente. Es mucho más fácil de entender que:

->cron(0, 0, *, *, *, *);

Repetir la tarea cada x minutos

En Laravel tenemos unas pocas funciones con algunos de las periodicidades más habituales relacionadas con los minutos:

  • everyMinute(): cada minuto.
  • everyFiveMinutes(): cada cinco minutos.
  • everyTenMinutes(): cada diez minutos.
  • everyThirtyMinutes(): cada treinta minutos.

Repetir tareas diariamente

También hay algunos métodos para repetir las tareas cada día:

  • daily(): cada día.
  • dailyAt('14:00'): cada día a las 14:00.
  • twiceDaily(10, 14): dos veces cada día, una a las 10:00 y otra a las 14:00.

Nota sobre twiceDaily(): Si no indicamos nada se repetirá cada día a las 1:00 y a las 13:00. Solo podemos indicar la hora, no los minutos.

Días de la semana

Por comodidad se han creado otras periodicidades para cada día de la semana. Por ejemplo, para ejecutar una tarea los lunes tenemos:

->mondays();

Y claro, tenemos una para cada día de la semana:

  • tuesdays(): martes.
  • wednesdays(): miércoles.
  • thrusdays(): jueves.
  • fridays(): viernes.
  • saturdays(): sábados.
  • sundays(): domingos.

También podemos indicar si queremos la tarea en días entre semana:

  • weekdays(): días laborables (de Lunes a Viernes).

Pero no, no hay opción para fines de semana.

Otras frecuencias

  • weekly(): cada semana. Se repite la tarea los Domingos a las 00:00. Es equivalente a $this->cron('0 0 * * 0 *');
  • montly(): mensualmente.
  • montlyOn(5, '15:00'): El día 5 de cada mes a las 15:00.
  • quarterly(): cada cuatrimestre.
  • yearly(): anualmente.

When()

Hay otra opción que nos permite limitar intervalos. Por ejemplo, si queremos una tarea que se ejecute todos los domingos cada hora pero solo entre las 10:00 y las 15:00:

$schedule->command('mails:send')->sundays()->hourly()->between('10:00', '15:00');

El formato de between() es:

->between( $comienzo, $fin );

UnlessBetween()

Tenemos un método opuesto al anterior, unlessBetween() se ejecutará en el periodo indicado excepto en el tramo que indiquemos:

$schedule->command('mails:send')->sundays()->hourly()->unlessBetween('10:00', '15:00');

Este comando se ejecutaría los domingos, cada hora excepto entre las 10 y las 15.

Encadenar métodos

Como ya hemos visto podemos encadenar todos los métodos anteriores para definir nuestra periodicidad. Por ejemplo, ejecutar un comando los domingos cada hora:

$schedule->command('mails:send')->sundays()->hourly();

Ver el resultado de la tarea

Por último tenemos dos métodos que nos permiten enviar la salida del comando a un fichero a modo de registro (log).

El primero de ellos es sendOutputTo:

$schedule->command('emails:send')
         ->daily()
         ->sendOutputTo($ficheroRegistro);

Si queremos conservar el contenido del fichero y añadir la nueva información al final del mismo podemos usar el método appendOutputTo:

$schedule->command('emails:send')
         ->daily()
         ->appendOutputTo($ficheroRegistro);

Más información

Hay algunos otros métodos y posibilidades para programar tareas. Puedes consultar la información completa en la documentación de la API de Laravel (este enlace es para la versión 5.3 de Laravel).

Autor:
Nivel: Intermedio
Palabras clave:
Fecha publicado:
Fecha actualizado: 14-09-2016

Otros capítulos de la misma serie

Este capítulo es parte de la serie: Laravel pearls.

Y muchos más en preparación.

Disponible en los planes: Laravel hero