aslain.dev
0%
01 Hizmetler 02 Hakkımda 03 Projeler 04 Stack 05 Blog 06 İletişim
← Tüm makaleler Développement Web

Laravel Scheduler : guide des tâches planifiées

Le Laravel scheduler vous permet de définir vos tâches périodiques directement dans le code de votre application, au lieu de lignes cron éparpillées sur le serveur. Des travaux comme générer des rapports nocturnes, purger d'anciens enregistrements, préchauffer le cache ou récupérer des données depuis une API se planifient à un seul endroit central, versionné, sans éditer le crontab à la main sur chaque serveur. Dans cet article, nous verrons étape par étape comment fonctionne le scheduler, comment définir votre première tâche, les options de fréquence disponibles et les points de vigilance en production.

Comment fonctionne le scheduler : une seule ligne cron

Dans l'approche classique, vous écrivez une entrée cron distincte pour chaque tâche planifiée. Dix tâches, c'est dix lignes dans le crontab du serveur ; elles vivent à l'écart de votre code, n'apparaissent jamais dans le contrôle de version et sont pénibles à migrer vers un nouveau serveur. Laravel inverse la logique : vous ajoutez une seule entrée cron sur le serveur et gérez tout le reste en PHP.

Ajoutez cette unique ligne au crontab du serveur :

* * * * * cd /path-to-your-project && php artisan schedule:run >> /dev/null 2>&1

Cette entrée exécute schedule:run chaque minute. La commande vérifie si une tâche est due à cet instant ; si oui, elle les déclenche, sinon elle sort silencieusement. Autrement dit, cron ne fournit qu'un « battement de cœur » — la logique qui décide quelle tâche tourne et quand réside entièrement du côté de Laravel.

Définir votre première tâche planifiée

À partir de Laravel 11 (Laravel 12 inclus), les définitions de planification se trouvent dans routes/console.php via la façade Schedule. L'ancien fichier app/Console/Kernel.php n'existe plus. L'exemple le plus simple est la commande intégrée inspire :

<?php

use Illuminate\Support\Facades\Schedule;

Schedule::command('inspire')->hourly();

Outre l'exécution de commandes, vous pouvez planifier trois types de travaux différents :

  • Schedule::command('emails:send') — exécute une commande artisan.
  • Schedule::job(new HeavyReport) — envoie un job dans la file d'attente.
  • Schedule::call(fn () => DB::table('sessions')->delete()) — exécute une closure ou un callable.

Pour lancer une commande shell, vous pouvez aussi utiliser Schedule::exec('node /scripts/import.js'). Dans la plupart des cas, le plus propre est d'encapsuler le travail dans une commande artisan et de planifier celle-ci.

Écrire votre propre commande

Créer votre propre commande artisan pour un travail récurrent regroupe la logique à un seul endroit et permet aussi de la lancer à la main. Générez la commande :

php artisan make:command SendDailyReport

Cela crée app/Console/Commands/SendDailyReport.php. Le $signature définit le nom de la commande et handle() définit ce qu'elle fait :

<?php

namespace App\Console\Commands;

use App\Models\Order;
use Illuminate\Console\Command;

class SendDailyReport extends Command
{
    protected $signature = 'report:daily';
    protected $description = 'Construit et envoie le rapport de ventes quotidien';

    public function handle(): int
    {
        $total = Order::whereDate('created_at', today())->sum('total');

        $this->info("Chiffre d'affaires du jour : {$total}");
        // ... envoyer par e-mail ou stocker le rapport

        return self::SUCCESS;
    }
}

Pour tester la commande, tapez simplement php artisan report:daily dans le terminal. Ajoutez ensuite la planification :

Schedule::command('report:daily')->dailyAt('07:30');

Fréquences et contraintes

Le scheduler propose une API lisible et fluide. Les fréquences les plus utilisées sont :

  • ->everyMinute(), ->everyFiveMinutes(), ->everyThirtyMinutes()
  • ->hourly(), ->hourlyAt(15) (à la minute 15 de chaque heure)
  • ->daily(), ->dailyAt('13:00'), ->twiceDaily(1, 13)
  • ->weekly(), ->monthly(), ->quarterly(), ->yearly()

Vous pouvez combiner ces fréquences avec des contraintes. Par exemple, une tâche qui ne tourne qu'en semaine, pendant les heures de bureau :

Schedule::command('report:daily')
    ->weekdays()
    ->between('9:00', '17:00')
    ->timezone('Europe/Paris');

Pour une exécution conditionnelle, utilisez ->when(fn () => Feature::active()), ou son inverse ->skip(...). Si les fréquences standard ne suffisent pas, vous pouvez passer une expression cron brute avec ->cron('0 */6 * * *'). Comme toutes ces méthodes se chaînent, même les plannings complexes s'expriment sur une seule ligne lisible.

Gérer les chevauchements et plusieurs serveurs

Deux problèmes importants apparaissent en production. Le premier est une tâche qui redémarre avant la fin de son exécution précédente. Protégez une tâche longue avec withoutOverlapping() :

Schedule::command('report:heavy')
    ->everyFiveMinutes()
    ->withoutOverlapping();

Le second survient quand vous exécutez la même application sur plusieurs serveurs, où chaque serveur déclenche la même tâche. Si vous voulez qu'une tâche ne tourne que sur un seul serveur, ajoutez onOneServer() (cela nécessite un pilote de cache Redis ou base de données) :

Schedule::command('report:daily')
    ->daily()
    ->onOneServer();

Pour éviter qu'une tâche ne retarde les autres, vous pouvez la lancer en arrière-plan avec runInBackground(). Vous pouvez aussi vous brancher sur le cycle de vie de la tâche avec before(), after(), onSuccess() et onFailure(), et rediriger sa sortie avec emailOutputTo() ou appendOutputTo().

Tester et surveiller en local

Pendant le développement, plutôt que d'attendre cron chaque minute, il existe une commande qui reste active au premier plan :

php artisan schedule:work

Tout comme cron sur le serveur, elle se déclenche chaque minute, mais reste dans votre terminal — idéale pour une machine de développement. Pour voir toutes les tâches définies avec leur prochaine exécution :

php artisan schedule:list

Si vous voulez exécuter et tester une tâche précise immédiatement, sans attendre son tour, php artisan schedule:test propose une liste interactive. Ces trois commandes vous permettent de répondre à « pourquoi ma tâche ne tourne-t-elle pas ? » en quelques secondes plutôt qu'en quelques minutes. En production, pour vous assurer que vos tâches s'exécutent réellement, vous pouvez pinger un service de surveillance (un « dead man's switch » par exemple) avec thenPing().

Questions fréquentes

Quelle est la différence entre schedule:run et schedule:work ?

schedule:run s'exécute une fois : il lance les tâches dues à l'instant présent puis sort ; le cron du serveur l'appelle chaque minute. schedule:work reste ouvert en tant que processus et se déclenche lui-même chaque minute en interne. Utilisez cron + schedule:run en production, et schedule:work en local.

Dois-je utiliser cron ou le Laravel scheduler ?

Les deux travaillent ensemble ; le scheduler ne remplace pas cron, il le réduit à une seule ligne. Toute votre logique de tâches reste en PHP, versionnée et testable ; sur le serveur, vous ne gérez qu'une seule entrée cron. C'est un confort énorme, surtout avec plusieurs tâches ou serveurs.

Ma tâche planifiée ne s'exécute pas — par où commencer ?

Vérifiez d'abord que l'entrée cron du serveur pointe vers le bon répertoire et le bon chemin PHP. Vérifiez ensuite avec php artisan schedule:list que la tâche est bien définie et planifiée à la bonne heure. La plupart des problèmes viennent d'un mauvais fuseau horaire ou d'une ligne cron manquante ou incorrecte.

Vous voulez mettre de l'ordre dans vos tâches planifiées ? Pour regrouper vos lignes cron éparpillées dans une seule structure de scheduler ou créer de nouveaux travaux périodiques, contactez-moi.

Bu kategorideki tüm yazılar →

Devamı için