Amit Merchant

Amit Merchant

A blog on PHP, JavaScript, and more

Probability-based randomness using Lottery class in Laravel 9.x

November 16, 2022 ·

A minor version of Laravel 9.x has just been released and with this release, a new Lottery class has been introduced.

As the name suggests, the Lottery class can be used to define a lottery and pick a winner based on the probability of each item.

How’s that? Let’s see.

The Lottery class

The Lottery class is a static class that can be used to define a lottery and pick a winner based on the probability of each item.

Here’s how you can define a lottery.

// routes/web.php

use Illuminate\Support\Lottery;

Route::get('/pick-winner', function () {
    echo Lottery::odds(1, 5)
            ->winner(fn () => 'You won!')
            ->loser(fn () => 'You lose!')
            ->choose();
}); 

As you can tell, the Lottery class has a odds method that accepts the number of winning chances ($chances) and the total number of chances ($outOf) as the first and second arguments respectively.

Next, you can define the winner and loser callbacks using the winner and loser methods respectively. These callbacks will be executed when the lottery is won or lost respectively.

Finally, you can pick a winner using the choose method.

For our example, we have defined a lottery with 1 winning chance out of 5 total chances. And if the lottery is won, we will return the string You won! and if the lottery is lost, we will return the string You lose!. One chance out of 5 is a 20% probability of winning.

Now, if you visit the /pick-winner route, you will get either the You won! or You lose! string.

Practical use case

Let’s say we are using the DB::whenQueryingForLongerThan method to detect and log queries that are taking longer than the specified time and we want to log only one query out of 50 slow queries, here’s how we can do that.

// app/Providers/AppServiceProvider.php

use Illuminate\Support\Lottery;

public function boot()
{
    DB::whenQueryingForLongerThan(
        Interval::seconds(2),
        Lottery::odds(1, 50)->winner(
            fn () => report('DB queries exceeded 2 seconds')
        )
    );
}

This can help prevent the log file from getting too big.

Or we can use the Lottery class to log only certain n+1 query issues like so.

Model::handleLazyLoadingViolationUsing(
    Lottery::odds(1, 5000)->winner(function ($model, $relation) {
        report(new LazyLoadingViolationException($model, $relation));
    })
);

Apart from this, this can be used in sceanrios where you’re planning to release a new feature and you only want to show it to a small numbers of users randomly.

Conclusion

This is a basic gist of the Lottery class in Laravel 9.x. But there are a lot more things that you can do with this class. So, I would recommend you to check out this PR to learn more about it.

Learn the fundamentals of PHP 8 (includes 8.1 and 8.2), the latest version of PHP, and how to use it today with my new book PHP 8 in a Nutshell. It's a no-fluff and easy-to-read guide to the latest features and nitty-gritty details of PHP 8. So, if you're looking for a quick and easy way to PHP 8, this is the book for you.

👋 Hi there! I'm Amit. I write articles about all things web development. If you like what I write and want me to continue doing the same, I would like you buy me some coffees. I'd highly appreciate that. Cheers!

Comments?