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

Laravel Scheduler: gids voor geplande taken

Met de Laravel scheduler definieer je je periodieke taken rechtstreeks in je applicatiecode in plaats van in verspreide cron-regels op de server. Werk zoals het genereren van nachtelijke rapporten, het opschonen van oude records, het opwarmen van de cache of het ophalen van data uit een API plan je op één centrale plek, opgenomen in versiebeheer, zonder op elke server handmatig de crontab te bewerken. In dit artikel lopen we stap voor stap door hoe de scheduler werkt, hoe je je eerste taak definieert, welke frequentie-opties er zijn en waar je in productie op moet letten.

Hoe de scheduler werkt: één cron-regel

In de klassieke aanpak schrijf je voor elke geplande taak een aparte cron-regel. Tien taken betekent tien regels in de crontab van de server; ze staan los van je code, verschijnen nooit in versiebeheer en zijn lastig te verhuizen naar een nieuwe server. Laravel draait dit om: je voegt slechts één cron-regel toe aan de server en beheert al het andere binnen PHP.

Voeg deze ene regel toe aan de crontab van de server:

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

Deze regel voert elke minuut schedule:run uit. Het commando controleert of er op dat moment een taak gepland staat; zo ja, dan start het die taken, anders stopt het stilletjes. Met andere woorden: cron levert alleen een "hartslag" — de logica die bepaalt welke taak wanneer draait, zit volledig aan de Laravel-kant.

Je eerste geplande taak definiëren

Vanaf Laravel 11 (inclusief Laravel 12) staan de planningsdefinities in routes/console.php via de Schedule-facade. Het oude bestand app/Console/Kernel.php bestaat niet meer. Het eenvoudigste voorbeeld is het ingebouwde inspire-commando:

<?php

use Illuminate\Support\Facades\Schedule;

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

Naast het uitvoeren van commando's kun je drie verschillende soorten werk plannen:

  • Schedule::command('emails:send') — voert een artisan-commando uit.
  • Schedule::job(new HeavyReport) — plaatst een job op de queue.
  • Schedule::call(fn () => DB::table('sessions')->delete()) — voert een closure of callable uit.

Om een shell-commando te draaien kun je ook Schedule::exec('node /scripts/import.js') gebruiken. In de meeste gevallen is de schoonste optie om het werk in een artisan-commando te verpakken en dat te plannen.

Je eigen commando schrijven

Een eigen artisan-commando maken voor terugkerend werk houdt de logica op één plek en laat je het ook handmatig draaien. Genereer het commando:

php artisan make:command SendDailyReport

Dit maakt app/Console/Commands/SendDailyReport.php. De $signature bepaalt de naam van het commando en handle() bepaalt wat het doet:

<?php

namespace App\Console\Commands;

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

class SendDailyReport extends Command
{
    protected $signature = 'report:daily';
    protected $description = 'Bouwt en verstuurt het dagelijkse verkooprapport';

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

        $this->info("Omzet van vandaag: {$total}");
        // ... rapport mailen of opslaan

        return self::SUCCESS;
    }
}

Om het commando te testen typ je gewoon php artisan report:daily in de terminal. Voeg daarna de planning toe:

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

Frequenties en beperkingen

De scheduler biedt een leesbare, vloeiende API. De meest gebruikte frequenties zijn:

  • ->everyMinute(), ->everyFiveMinutes(), ->everyThirtyMinutes()
  • ->hourly(), ->hourlyAt(15) (op minuut 15 van elk uur)
  • ->daily(), ->dailyAt('13:00'), ->twiceDaily(1, 13)
  • ->weekly(), ->monthly(), ->quarterly(), ->yearly()

Je kunt deze frequenties combineren met beperkingen. Bijvoorbeeld een taak die alleen op werkdagen tijdens kantooruren draait:

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

Voor voorwaardelijke uitvoering gebruik je ->when(fn () => Feature::active()), of het omgekeerde ->skip(...). Als de standaardfrequenties niet volstaan, kun je met ->cron('0 */6 * * *') een ruwe cron-expressie meegeven. Omdat al deze methoden ketenbaar zijn, druk je zelfs complexe planningen op één leesbare regel uit.

Overlap en meerdere servers beheren

In productie duiken twee belangrijke problemen op. Het eerste is een taak die opnieuw start voordat de vorige run klaar is. Bescherm een langlopende taak met withoutOverlapping():

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

Het tweede speelt wanneer je dezelfde applicatie op meerdere servers draait, waarbij elke server dezelfde taak afvuurt. Wil je dat een taak op slechts één server draait, voeg dan onOneServer() toe (dit vereist een Redis- of database-cachedriver):

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

Om te voorkomen dat één taak de andere vertraagt, kun je hem op de achtergrond draaien met runInBackground(). Je kunt ook inhaken op de levenscyclus van de taak met before(), after(), onSuccess() en onFailure(), en de uitvoer omleiden met emailOutputTo() of appendOutputTo().

Lokaal testen en monitoren

Tijdens de ontwikkeling is er, in plaats van elke minuut op cron wachten, een commando dat op de voorgrond blijft draaien:

php artisan schedule:work

Net als cron op de server wordt dit elke minuut getriggerd, maar het blijft in je terminal — ideaal voor een ontwikkelmachine. Om alle gedefinieerde taken met hun volgende uitvoeringstijden te zien:

php artisan schedule:list

Wil je een specifieke taak meteen draaien en testen, zonder op de beurt te wachten, dan biedt php artisan schedule:test een interactieve lijst. Met deze drie commando's beantwoord je "waarom draait mijn taak niet?" in seconden in plaats van minuten. In productie kun je, om zeker te zijn dat je taken echt draaien, een monitoringservice (zoals een "dead man's switch") pingen met thenPing().

Veelgestelde vragen

Wat is het verschil tussen schedule:run en schedule:work?

schedule:run draait eenmalig: het voert de taken uit die nu gepland staan en stopt dan; de cron op de server roept het elke minuut aan. schedule:work blijft als proces open en triggert zichzelf intern elke minuut. Gebruik cron + schedule:run in productie, en schedule:work lokaal.

Moet ik cron of de Laravel scheduler gebruiken?

Ze werken samen; de scheduler vervangt cron niet, maar reduceert hem tot één regel. Al je taaklogica blijft in PHP, in versiebeheer en testbaar; op de server beheer je slechts één cron-regel. Dat is een enorm gemak, zeker bij meerdere taken of servers.

Mijn geplande taak draait niet — waar begin ik?

Controleer eerst of de cron-regel op de server naar de juiste map en het juiste PHP-pad wijst. Controleer daarna met php artisan schedule:list of de taak echt gedefinieerd en op het juiste tijdstip gepland is. De meeste problemen komen door een verkeerde tijdzone of een ontbrekende of foutieve cron-regel.

Wil je je geplande taken op orde brengen? Om je verspreide cron-regels samen te brengen in één scheduler-opzet of nieuwe periodieke taken op te zetten, neem contact met me op.

Bu kategorideki tüm yazılar →

Devamı için