Cómo usar la Caché en Laravel

Laravel

En este tutorial vamos a ver cómo usar la caché de Laravel. Aprenderás a configurarla y a almacenar, obtener y eliminar datos de la misma, entre otras funciones.

Laravel ofrece un sistema de caché integrado y flexible que soporta una amplia gama de drivers de caché, como File, Redis, Memcached, APC, Array, y más. Esta funcionalidad permite mejorar el rendimiento de las aplicaciones almacenando temporalmente ciertos datos que son costosos de obtener, como respuestas de bases de datos, llamadas a API o cálculos complejos. A continuación, veremos varios aspectos importantes del sistema de caché en Laravel.

Configuración de la caché

La configuración de caché en Laravel se encuentra en config/cache.php. Aquí puedes definir diferentes stores de caché, cada uno con su propio driver. Laravel soporta varios drivers de caché:

  • File: Almacena los datos de caché en el sistema de archivos.
  • Database: Utiliza una base de datos para almacenar los datos de caché.
  • Memcached / Redis: Almacena los datos en sistemas de caché en memoria, ideales para entornos de producción por su rapidez.
  • Array: No almacena datos entre solicitudes; útil para pruebas y desarrollo.
  • APC: Utiliza el caché de opcode APC.
  • DynamoDB: Usa la base de datos NoSQL de AWS como sistema de caché.

Puedes cambiar el driver predeterminado modificando la variable de entorno CACHE_DRIVER en tu archivo .env.

Para usar la caché, puedes usar tanto la fachada Cache de Laravel como el helper cache().

Cómo almacenar datos en caché

Almacenar un valor en el sistema de caché de Laravel es muy sencillo y se puede hacer de varias maneras, utilizando la fachada Cache o el helper global cache(). Aquí te muestro cómo hacerlo.

Primero, asegúrate de importar la fachada Cache en la parte superior de tu archivo:

use Illuminate\Support\Facades\Cache;

Luego, puedes almacenar un valor en caché especificando una clave, un valor y el tiempo de duración en minutos. Aquí tienes un ejemplo:

Cache::put('clave', 'valor', $minutos);

Si prefieres especificar el tiempo de expiración en segundos, puedes usar una instancia de Carbon para hacerlo más legible:

use Carbon\Carbon;

Cache::put('clave', 'valor', Carbon::now()->addSeconds(10));

También hay un método útil si solo quieres cachear algo para siempre, o hasta que sea manualmente eliminado:

Cache::forever('clave', 'valor');

Has de saber que también puedes recordar un patrón usando el método el método remember ,que busca un elemento en la caché y, si no lo encuentra, ejecuta el callback dado, almacena el resultado en caché y luego lo retorna. Esto simplifica el patrón de verificar el caché o, en su defecto, calcular y almacenar.

$value = Cache::remember('users', $seconds, function () {
    return DB::table('users')->get();
});

Supongamos que quieres almacenar los resultados de una consulta costosa, como la lista de todos los usuarios de tu aplicación, y quieres que esta caché dure 30 minutos:

use Illuminate\Support\Facades\Cache;
use App\Models\User;

$usuarios = Cache::remember('usuarios', 30, function () {
    return User::all();
});

Además, también puedes usar el helper cache(), que proporciona una forma rápida y conveniente de interactuar con el sistema de caché. Puedes almacenar un valor en caché de esta manera:

cache(['clave' => 'valor'], $minutos);

Para almacenar un valor indefinidamente, puedes pasar null como el segundo argumento:

cache(['clave' => 'valor'], null);

Cómo obtener datos de la caché

Para obtener un valor almacenado en el sistema de caché de Laravel, puedes usar la fachada Cache o el helper cache(). Ambas opciones ofrecen una interfaz simple para acceder a los datos en caché.

Para usar la fachada, primero asegúrate de importar la fachada Cache en la parte superior de tu archivo si aún no lo has hecho:

use Illuminate\Support\Facades\Cache;

Luego, puedes recuperar un valor de la caché utilizando el método get(), especificando la clave que utilizaste para almacenar el valor:

$value = Cache::get('clave');

Si quieres proporcionar un valor predeterminado para usar en caso de que la clave especificada no exista en la caché, puedes pasar un segundo argumento al método get():

$value = Cache::get('clave', 'valor predeterminado');

El helper cache() también permite recuperar valores de la caché de una manera concisa. Si pasas solo la clave como argumento, intentará obtener el valor asociado con esa clave:

$value = cache('clave');

Al igual que con la fachada Cache, puedes especificar un valor predeterminado como segundo argumento, que se utilizará si la clave no se encuentra en la caché:

$value = cache('clave', 'valor predeterminado');

Supongamos que has almacenado previamente una lista de categorías en la caché y ahora deseas recuperarla. Aquí está cómo podrías hacerlo, proporcionando un arreglo vacío como valor predeterminado en caso de que la clave no exista:

$categorias = Cache::get('categorias', []);

O utilizando el helper cache():

$categorias = cache('categorias', []);

Con la fachada Cache, también puedes pasar una closure como segundo argumento al método get(). Si la clave no existe en la caché, Laravel ejecutará la closure, almacenará su resultado en la caché con la clave especificada, y luego retornará ese valor. Este es un patrón comúnmente utilizado con el método remember(), como se mencionó anteriormente.

Cómo eliminar datos de la caché

Eliminar datos de la caché en Laravel es una operación simple que se puede realizar utilizando la fachada Cache. Laravel ofrece varias maneras de hacerlo, dependiendo de tus necesidades específicas.

Para eliminar un elemento específico de la caché utilizando su clave:

use Illuminate\Support\Facades\Cache;

Cache::forget('clave');

Si necesitas limpiar o eliminar todos los elementos almacenados en la caché, puedes utilizar el método flush:

Cache::flush();

Ten en cuenta que flush eliminará todos los elementos de la caché, independientemente del store de caché que estés utilizando, lo que podría afectar el rendimiento de tu aplicación si se usa indiscriminadamente.

Si has etiquetado tus elementos de caché y solo deseas eliminar elementos específicos bajo una o varias etiquetas, puedes hacerlo así:

Cache::tags(['etiqueta1', 'etiqueta2'])->flush();

Cómo comprobar la existencian de valores en caché

Para comprobar si un elemento existe en la caché en Laravel, puedes utilizar el método has de la fachada Cache. Este método retorna true si el elemento especificado existe en la caché, de lo contrario, retorna false.

Primero, asegúrate de importar la fachada Cache en tu archivo, si aún no lo has hecho:

use Illuminate\Support\Facades\Cache;

Luego, puedes comprobar si un elemento existe en la caché de la siguiente manera:

if (Cache::has('clave')) {
    // El elemento existe en la caché
} else {
    // El elemento no existe en la caché
}

Supongamos que estás almacenando información de configuración en la caché y quieres verificar si ya está almacenada antes de intentar recuperarla o calcularla nuevamente:

$claveConfiguracion = 'configuracion_usuario_' . auth()->id();

if (Cache::has($claveConfiguracion)) {
    $configuracion = Cache::get($claveConfiguracion);
} else {
    // Supongamos que getConfiguracionUsuario() es un método que recupera
    // la configuración del usuario desde una base de datos o un servicio externo.
    $configuracion = $this->getConfiguracionUsuario();

    // Almacenar la configuración en la caché para futuros usos
    Cache::put($claveConfiguracion, $configuracion, 3600); // 1 hora
}

Este patrón es particularmente útil para evitar la repetición innecesaria de operaciones costosas, como consultas a bases de datos o llamadas a APIs, mediante el almacenamiento en caché de los resultados.

Ten en cuenta que el método has solo verifica si un elemento existe en la caché, pero no garantiza que el elemento no haya expirado en el momento en que intentas recuperarlo. En escenarios donde el tiempo de vida del elemento en caché es crítico, podrías considerar recuperar el elemento directamente con get o remember, lo que asegura que obtienes un valor fresco o calculado recientemente si el elemento ha expirado o no existe.

Aunque verificar la existencia de un elemento en caché es generalmente rápido, el uso excesivo de esta operación en sistemas de alta carga podría tener un impacto en el rendimiento. Diseña cuidadosamente tu lógica de caché para minimizar las comprobaciones innecesarias y maximizar la eficiencia.

Cómo incrementar un valor en caché

El método increment de la caché de Laravel te permite aumentar el valor de un elemento numérico almacenado en la caché, lo cual es muy útil para llevar conteos o totales que se actualizan con frecuencia. De manera similar, existe el método decrement para disminuir el valor..P

Primero, asegúrate de importar la fachada Cache si aún no lo has hecho:

use Illuminate\Support\Facades\Cache;

Para incrementar un valor en la caché:

Cache::increment('contador');

Por defecto, esto aumentará el valor de contador en 1. Si el contador no existe, será creado con un valor de 1.

Puedes especificar un segundo argumento para incrementar por un valor diferente de 1:

Cache::increment('contador', 10); // Aumenta el valor de 'contador' en 10

Supongamos que estás construyendo una aplicación que necesita rastrear cuántas veces se ha visitado una página en particular. Podrías utilizar increment para actualizar este conteo cada vez que la página es solicitada:

public function incrementPageVisits($pageId)
{
    // Aumenta el contador de visitas para la página específica
    $visitas = Cache::increment('visitas.' . $pageId);

    return $visitas;
}

En el ejemplo anterior, si suponemos que $pageId es un identificador único para una página, estarías creando y actualizando un contador específico para cada página usando su ID en la clave de caché.

Asegúrate de que la clave que intentas decrementar esté almacenada como un número en la caché. De manera similar, si necesitas reducir el contador por alguna razón, puedes usar el método decrement, que veremos a continuación.

Cómo decrementar un valor en caché

El método decrement en Laravel funciona de manera similar a increment, pero en lugar de aumentar, disminuye el valor de un elemento numérico almacenado en la caché. Es útil para operaciones como disminuir conteos, realizar seguimiento de límites de uso, entre otros.

Primero, si aún no lo has hecho, asegúrate de importar la fachada Cache:

use Illuminate\Support\Facades\Cache;

Para disminuir un valor en la caché por 1 (el valor predeterminado):

Cache::decrement('contador');

Si el contador no existe, Laravel lo creará con un valor de -1.

Puedes especificar un segundo argumento para decrementar el valor por una cantidad diferente de 1:

Cache::decrement('contador', 5); // Disminuye el valor de 'contador' en 5

Imagina que estás desarrollando una aplicación que limita cuántas veces un usuario puede realizar cierta acción dentro de un periodo de tiempo. Podrías usar decrement para actualizar este límite cada vez que el usuario realiza la acción:

public function updateActionLimit($userId)
{
    // Supón que cada usuario puede realizar la acción 100 veces por hora.
    // Al inicio de cada hora, restableces este contador a 100.
    // Cada vez que el usuario realiza la acción, decrementas este contador.

    $acciones= Cache::decrement('acciones_restantes.' . $userId);

    if ($acciones >= 0) {
        // Permitir la acción
    } else {
        // Bloquear la acción y notificar al usuario de que se ha alcanzado el límite
    }

    return $acciones;
}

Al igual que con increment, asegúrate de que la clave que intentas decrementar esté almacenada como un número en la caché.

Cómo usar etiquetas de caché

Las etiquetas de caché en Laravel te permiten agrupar elementos de caché relacionados, lo que facilita su gestión al permitirte realizar acciones como invalidar todos los elementos de caché asociados con una etiqueta específica. Sin embargo, es importante mencionar que no todos los drivers de caché soportan las etiquetas de caché; por ejemplo, los drivers como file y database no las soportan, mientras que Redis y Memcached sí.

Primero, asegúrate de que estás utilizando un driver de caché que soporte etiquetas. Puedes configurar esto en tu archivo .env, por ejemplo, usando Memcached:

CACHE_DRIVER=memcached

Para almacenar un elemento en caché y asociarlo con una o más etiquetas, puedes usar el método tags de la fachada Cache. Aquí un ejemplo:

use Illuminate\Support\Facades\Cache;

Cache::tags(['etiqueta1', 'etiqueta2'])->put('miClave', 'miValor', $minutos);

Este código almacenará el elemento miClave con el valor miValor en la caché y lo asociará con las etiquetas etiqueta1 y etiqueta2.

Para recuperar un elemento de la caché que ha sido almacenado con etiquetas, usa el mismo método tags:

$value = Cache::tags(['etiqueta1', 'etiqueta2'])->get('miClave');

Una de las principales ventajas de usar etiquetas de caché es la capacidad de invalidar todos los elementos asociados con una etiqueta específica sin afectar a otros elementos de caché. Para hacerlo, utiliza el método flush en una instancia de caché etiquetada:

Cache::tags(['etiqueta1'])->flush();

Este comando eliminará todos los elementos de caché que estén asociados con etiqueta1, pero dejará intactos los elementos asociados únicamente con etiqueta2.

Supongamos que tienes una aplicación de blog y quieres cachear los posts y comentarios. Podrías querer invalidar todos los elementos de caché relacionados con los posts sin afectar a los comentarios:

// Almacenar un post en caché
Cache::tags(['posts'])->put('post:1', $post, now()->addHour());

// Almacenar un comentario en caché
Cache::tags(['comments'])->put('comment:1', $comment, now()->addHour());

// Más tarde, si actualizas o eliminas un post, podrías querer invalidar todos los posts caché
Cache::tags(['posts'])->flush();

Ten en cuenta que el uso de etiquetas puede afectar el rendimiento, especialmente al invalidar grandes cantidades de elementos etiquetados. Usa esta característica con prudencia. Asegúrate también de que el driver de caché que elijas soporta etiquetas. Revisa la documentación oficial de Laravel para obtener la lista más actualizada de drivers compatibles.


Avatar de Edu Lazaro

Edu Lázaro: Ingeniero técnico en informática, actualmente trabajo como desarrollador web y programador de videojuegos.

👋 Hola! Soy Edu, me encanta crear cosas y he redactado esta guía. Si te ha resultado útil, el mayor favor que me podrías hacer es el de compatirla en Twitter 😊

Si quieres conocer mis proyectos, sígueme en Twitter.

Deja una respuesta

“- Hey, Doc. No tenemos suficiente carretera para ir a 140/h km. - ¿Carretera? A donde vamos, no necesitaremos carreteras.”