Introduction
This little trick comes from the frustration of forgetting the language code in the cache key, inside the Cache helper of Laravel.
Suppose that in a multilingual blog you are visiting the home page for the first time, using the default language (e.g. English). If the website caches the posts to speed up the response, maybe using the following code
<?php
$posts = Cache::rememberForever('posts', function() {
return DB::table('posts')->where('lang', app()->getLocale())->get();
});
if you visit the same website using a different language you will get the English version of the posts, because they are stored in cache with the same key (posts
). Therefore the callback is skipped entirely.
You can solve this problem by using the language code in the cache key, in the following way:
<?php
$posts = Cache::rememberForever(app()->getLocale() . '.posts', function() {
return DB::table('posts')->where('lang', app()->getLocale())->get();
});
However you need to specify the language code every time you use the cache helper. In the long distance it might get boring and prone to subtle bugs, if you forget to add it.
Solution
There’s a more elegant solution, which leverages the macroable Trait in Laravel Cache facade. This means that you can extend the Cache
class with new methods. For example let’s add a language-aware rememberForever
method in the AppServiceProvider
:
<?php
Cache::macro('langAwareRememberForever', function ($key, Closure $callback)
{
return Cache::rememberForever(app()->getLocale() . '.' . $key, $callback);
});
so you can use it in your code, without worrying to write the language code.
<?php
$posts = Cache::langAwareRememberForever('posts', function() {
return DB::table('posts')->where('lang', app()->getLocale())->get();
});
If you want to know how the things work under the hood with the Macroable trait, take a look at this article.