Skip to main content

Was ist die Lottery-Klasse?

Illuminate\Support\Lottery ist eine Utility-Klasse, mit der Sie wahrscheinlichkeitsbasierte Operationen in einer Fluent API ausdrücken. Muster wie „nur jede 100. Anfrage ausführen” oder „nur bei einem Teil der Anfragen ausführliches Logging” lassen sich damit prägnant beschreiben.
Die Implementierung befindet sich in src/Illuminate/Support/Lottery.php. Laravel setzt diese Klasse selbst intern ein, etwa für Session-GC oder das Prunen abgelaufener Cache-Locks.

Grundlegende Verwendung

Wahrscheinlichkeit als Ganzzahl-Verhältnis

Mit Lottery::odds($chances, $outOf) geben Sie die Wahrscheinlichkeit als „chancesvonchances von outOf Fällen” an.

Wahrscheinlichkeit als Dezimalzahl

Wenn Sie $outOf weglassen und einen Dezimalwert zwischen 0.0 und 1.0 übergeben, wird dieser als Wahrscheinlichkeit verwendet.
Übersteigt der Dezimalwert 1.0, wird eine RuntimeException geworfen.

Boolean-Rückgabe ohne Callbacks

Ohne gesetzte winner-/loser-Callbacks liefert choose() true im Gewinnfall und false andernfalls.

Mehrmalige Ausführung

Übergeben Sie choose($times) eine Anzahl, wird ein Array mit den Ergebnissen zurückgegeben.

Als Callable weitergeben

Da Lottery __invoke implementiert, können Sie eine Instanz direkt an APIs übergeben, die ein Callable erwarten.

Praktische Anwendungsfälle

1. Cache Prunen (nur 1 von 100 Fällen)

Ideal für Wartungsaufgaben wie das Entfernen abgelaufener Einträge, die nicht bei jedem Aufruf laufen müssen.

2. Telemetrie-Sampling (Detail-Logs nur für einen Teil der Anfragen)

Wenn das Loggen jeder Anfrage zu teuer ist, eignet sich Sampling.

3. A/B-Test-artiges Verhalten

Nutzer werden probabilistisch auf zwei Code-Pfade verteilt.

4. Als Ergänzung zum Scheduler zufällige Tasks ausführen

Nützlich, wenn Sie einen Task zufällig ausführen wollen, ohne dass mehrere Server ihn doppelt starten.

Probabilistische Muster im Laravel-Framework

Laravel selbst nutzt intern in vielen Fällen probabilistische Wartungsroutinen. Einige Implementierungen entstanden vor der Einführung der Lottery-Klasse und verwenden direkt random_int() — der Grundgedanke ist derselbe.
1

Session: Garbage Collection

Illuminate\Session\Middleware\StartSession::configHitsLottery() liest die Einstellung lottery aus config/session.php und entscheidet mit random_int über die GC-Ausführung.
2

DatabaseLock: Prunen abgelaufener Locks

Illuminate\Cache\DatabaseLock::acquire() löscht bei jedem Lock-Erwerb nach demselben Verhältnis abgelaufene Locks.
3

DB::whenQueryingForLongerThan — Beispiel mit übergebener Lottery-Klasse

Da eine Lottery-Instanz als Callable verwendbar ist, lässt sie sich direkt als Slow-Query-Callback nutzen.
Während Session und DatabaseLock direkt random_int() nutzen, bietet die Lottery-Klasse den Vorteil, die Ergebnisse per alwaysWin(), alwaysLose() oder fix() für Tests zu steuern. In der Paketentwicklung erhöht die Wahl von Lottery die Testbarkeit.

Verwendung in Tests

Für Tests von Code mit Zufall nutzen Sie die Test-API von Lottery.

Lottery::alwaysWin() — immer gewinnen

Lottery::alwaysLose() — immer verlieren

Lottery::fix() — Ergebnisse als Sequenz festlegen

Sie können die Ergebnisse mehrerer Aufrufe als Array aus true/false steuern.
alwaysWin(), alwaysLose() und fix() verändern globale statische Eigenschaften. Rufen Sie in tearDown() unbedingt Lottery::determineResultNormally() auf.

Lottery::setResultFactory() — eigene Factory injizieren

Für feinere Kontrolle nutzen Sie eine eigene Factory.

Einsatz in der Paketentwicklung

Registrierung im Service Provider

Wenn Sie Wartungsroutinen in den Service Provider Ihres Pakets einbauen, verteilen Sie mit Lottery die Last.

Wahrscheinlichkeit aus der Konfiguration lesen

Machen Sie die Wahrscheinlichkeit über eine Config-Datei änderbar, damit Nutzer sie leichter anpassen können.

Sampling in einer Middleware

API-Referenz

Verwandte Seiten

Macroable-Trait

Lernen Sie das Erweiterungsmuster kennen, um bestehenden Klassen neue Methoden hinzuzufügen.

Conditionable-Trait

Lernen Sie den Entwurf von Bedingungs-Chains mit when() / unless() kennen.
Zuletzt geändert am 13. Juli 2026