Maison  >  Article  >  cadre php  >  Comment mettre en cache les données au niveau de la couche Modèle dans Laravel ?

Comment mettre en cache les données au niveau de la couche Modèle dans Laravel ?

Guanhui
Guanhuiavant
2020-06-11 09:21:073246parcourir

Comment mettre en cache les données au niveau de la couche Modèle dans Laravel ?

Vous avez peut-être mis en cache des données de modèle avant cela, mais je vais vous montrer une technique de mise en cache de modèles Laravel plus élaborée utilisant des modèles enregistrés dynamiquement, que j'ai commencé avec les techniques apprises par RailsCasts.

À l'aide de la clé de cache unique du modèle, vous pouvez mettre en cache des propriétés et des associations sur le modèle qui se mettent automatiquement à jour (et invalident le cache) lorsque le modèle (ou le modèle associé) est mis à jour. L'un des avantages est que l'accès aux données mises en cache est plus rapide. que dans le contrôleur. Les données mises en cache sont plus réutilisables car elles se trouvent sur le modèle plutôt que dans une méthode de contrôleur unique.

C'est le point clé de cette technologie :

Supposons que vous ayez de nombreux modèles d'articles de commentaires, étant donné le modèle de lame Laravel suivant, vous pouvez accéder à la route /article/:id comme ceci lorsque vous obtenir le nombre de commentaires :

<h3>$article->comments->count() {{ str_plural(&#39;Comment&#39;, $article->comments->count())</h3>

Vous pouvez mettre en cache le nombre de commentaires dans le contrôleur, mais lorsque vous avez plusieurs requêtes ponctuelles et données qui doivent être mises en cache, le contrôleur peut devenir très gonflé et laid. À l'aide de contrôleurs, l'accès aux données mises en cache n'est pas non plus très pratique.

Nous pouvons créer un modèle qui accède à la base de données uniquement lorsque l'article est mis à jour, et tout le code qui accède au modèle peut obtenir la valeur mise en cache :

<h3>$article->cached_comments_count {{ str_plural(&#39;Comment&#39;, $article->cached_comments_count)</h3>

En utilisant l'accesseur de modèle, nous pouvons cache Nombre de commentaires basé sur la dernière mise à jour de l'article.

Alors, comment devons-nous mettre à jour la valeur de la colonne update_at de l'article lorsqu'un commentaire est ajouté ou supprimé ?

Entrez d'abord la méthode tactile pour y jeter un œil.

Déclenchement du modèle

Vous pouvez mettre à jour la valeur de la colonne update_at de l'article en utilisant la méthode touch() du modèle :

$ php artisan tinker

>>> $article = \App\Article::first();
=> App\Article {#746
     id: 1,
     title: "Hello World",
     body: "The Body",
     created_at: "2018-01-11 05:16:51",
     updated_at: "2018-01-11 05:51:07",
   }
>>> $article->updated_at->timestamp
=> 1515649867
>>> $article->touch();
=> true
>>> $article->updated_at->timestamp
=> 1515650910

Nous pouvons invalider le cache avec une valeur d'horodatage mise à jour. Mais lors de l’ajout ou de la suppression d’un commentaire, comment déclencher la modification du champ update_at de l’article ?

Il arrive qu'il y ait une propriété dans le modèle Eloquent appelée $touches . Voici à quoi ressemble notre modèle de commentaire :

<?php
namespace App;
use App\Article;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    protected $guarded = [];
    protected $touches = [&#39;article&#39;];
    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}

La propriété $touches ici est un tableau qui contient les informations associées qui provoqueront des « déclencheurs » lorsque le commentaire est créé, enregistré et supprimé.

Propriétés mises en cache

Retournons à l'accesseur $article->cached_comments_count. L'implémentation de cette méthode pourrait ressembler à ceci dans le modèle AppArticle :

public function getCachedCommentsCountAttribute()
{
    return Cache::remember($this->cacheKey() . &#39;:comments_count&#39;, 15, function () {
        return $this->comments->count();
    });
}

Nous mettons en cache le modèle pendant 15 minutes en utilisant la méthode cacheKey() de la clé unique, puis renvoyons simplement le nombre de révisions dans la méthode de fermeture .

Notez que nous utilisons également la méthode Cache::rememberForever(), en nous appuyant sur la stratégie de garbage collection du mécanisme de cache pour supprimer les valeurs de clé expirées. J'ai configuré une minuterie pour que pendant l'intervalle d'actualisation du cache toutes les 15 minutes, le cache ait le taux de réussite le plus élevé pendant la majeure partie de ce temps.

La méthode cacheKey() utilise la valeur de clé unique du modèle, et le cache sera invalidé lors de la mise à jour du modèle. Voici mon code d'implémentation cacheKey :

public function cacheKey()
{
    return sprintf(
        "%s/%s-%s",
        $this->getTable(),
        $this->getKey(),
        $this->updated_at->timestamp
    );
}

L'exemple de méthode cacheKey() du modèle peut renvoyer les informations de chaîne suivantes :

articles/1-1515650910

Cette valeur de clé est composée du nom de la table et de l'identifiant du modèle. et la valeur d'horodatage du update_at actuel. Une fois que nous aurons déclenché ce modèle, la valeur de l'horodatage sera mise à jour et notre cache de modèle sera invalidé en conséquence.

Voici le code complet du modèle Article :

<?php
namespace App;
use App\Comment;
use Illuminate\Support\Facades\Cache;
use Illuminate\Database\Eloquent\Model;
class Article extends Model
{
    public function cacheKey()
    {
        return sprintf(
            "%s/%s-%s",
            $this->getTable(),
            $this->getKey(),
            $this->updated_at->timestamp
        );
    }
    public function comments()
    {
        return $this->hasMany(Comment::class);
    }
    public function getCachedCommentsCountAttribute()
    {
        return Cache::remember($this->cacheKey() . &#39;:comments_count&#39;, 15, function () {
            return $this->comments->count();
        });
    }
}

Et puis le modèle Commentaire associé :

<?php
namespace App;
use App\Article;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
    protected $guarded = [];
    protected $touches = [&#39;article&#39;];
    public function article()
    {
        return $this->belongsTo(Article::class);
    }
}

Et ensuite ?

Je vous ai montré comment mettre en cache un simple nombre de commentaires, mais qu'en est-il de la mise en cache de tous les commentaires ?

public function getCachedCommentsAttribute()
{
    return Cache::remember($this->cacheKey() . &#39;:comments&#39;, 15, function () {
        return $this->comments;
    });
}

Vous pouvez également choisir de convertir les commentaires en tableau au lieu de sérialiser le modèle, permettant uniquement un simple accès au tableau aux données sur le frontend :

public function getCachedCommentsAttribute()
{
    return Cache::remember($this->cacheKey() . &#39;:comments&#39;, 15, function () {
        return $this->comments->toArray();
    });
}

Enfin, j'ai défini la cacheKey dans la méthode Article model (), mais vous souhaiterez peut-être définir cette méthode via un trait appelé ProvidesModelCacheKey afin de pouvoir l'utiliser dans un modèle composite ou définir la méthode pour toutes les extensions de modèle dans un modèle de base. Vous souhaiterez peut-être même utiliser un contrat (interface) pour votre modèle qui implémente la méthode cacheKey().

Tutoriels recommandés : "Tutoriel PHP" "Laravel"

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Cet article est reproduit dans:. en cas de violation, veuillez contacter admin@php.cn Supprimer