once() helper function in Laravel

In a nutshell, once() helper function of Laravel runs the codes inside it’s callback only once in a request lifecycle and caches it so that when you make another call later it will return the cached value instead of running the codes inside the callback again. Let’s see that in more details with some examples now.

The once() function can be really useful specially in Database Relations that does not change frequently, API requests, processing large amount of data and other places.

NOTE: The once() helper function was released in Laravel 11.

Syntax

once(callable $callback): mixed

$callback: A callable (function or closure) that you want to run only once.

Examples

Here’s a basic example to understand how once() helper function works:

public function getTimestamp()
{
    return once(function () {
        return now(); // Get the current timestamp.
    });
}

// Usage:
echo $this->getTimestamp(); // First call: calculates and caches the timestamp.
sleep(2);
echo $this->getTimestamp(); // Subsequent calls: returns the cached timestamp.

This is a perfect example to understand the once() helper function. Here we are caching the timestamp (which changes very frequently) with the once() helper function, when you first call the method getTimestamp(), it will calculate the timestamp and returns it but also caches it. If you call the same method the second time, it will return the cached version. One thing to note though is that it will recalculate and re-cache it if it’s a new request (refreshing the page).

Now let’s see a realistic use case of this helper function:

class Order extends Model
{
    public function products()
    {
        return $this->hasMany(Product::class);
    }

    public function cachedProducts()
    {
        return once(function () {
            return $this->products()->get(); // Cache the related products.
        });
    }
}

// Usage:
$order = Order::find(1);

$order->cachedProducts(); // Fetches and caches the related products.
$order->cachedProducts(); // Uses the cached result.

This is where once() helper function can be really useful. If you have an Order model with a products relationship, then most probably the products of the order won’t change at least within the same request. The once() helper can be used to cache the relationship query results so that you aren’t sending requests to your database each time you need the products of the order.

Disabling, Enabling & Flushing once()

You can disable and re-enable the once() helper function and you can also flush the caches generated by the once() helper function. This can be very useful while writing tests.

Here’s an example of disabling, enabling and flushing the caches of once():

use Illuminate\Support\Facades\Once;

// Disabling once() globally
Once::disable();

$result = once(function () {
    return now();
});

echo $result; // Executes every time since caching is disabled.

// Flushing the cache
Once::enable();
Once::flush();

Laravel has created a video on the once() helper function, if you prefer visual examples then you can watch this:

If you liked the content and want support this site, you can do so by buying me a coffee.

Leave a Comment