Use language-aware cache helper in Laravel

 Reading time ~2 minutes

Heads up: this article is over a year old. Some information might be out of date, as I don't always update older articles.

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.

comments powered by Disqus

Remove duplicate rows from MySQL table

Introduction

Suppose that we have a MySQL table with the following fields:

SHOW COLUMNS FROM survey_responses; …