Maison > développement back-end > tutoriel php > Exemples d'applications pratiques de Redis dans les projets Laravel

Exemples d'applications pratiques de Redis dans les projets Laravel

巴扎黑
Libérer: 2023-03-14 22:16:02
original
2218 Les gens l'ont consulté

Cet article vous présente principalement les informations pertinentes sur l'application de Redis dans le projet Laravel. L'article le présente en détail à travers un exemple de code. Il a une certaine valeur d'apprentissage de référence pour que tous puissent apprendre ou utiliser Laravel. cela peut suivre ci-dessous. Apprenons ensemble.

Avant-propos

Cet article vous présente principalement les exemples d'application du projet Redis dans Laravel et les partage pour votre référence et votre étude. mots suivants Sans plus tarder, jetons un œil à l'introduction détaillée :

Après une compréhension préliminaire de l'application de Redis dans Laravel, imaginons un tel scénario d'application si les statistiques du nombre de vues d'un. l'article ou le message ne fait qu'augmenter à chaque fois. Une page vue

ajoute une nouvelle donnée à la base de données. Si la requête est trop volumineuse, il va de soi qu'elle consomme la base de données.

La solution ici est que même si votre site Web a un grand nombre de requêtes, effectuez des modifications dans le cache à chaque fois qu'une visite est ajoutée. Quant à l'actualisation de la base de données Mysql, vous pouvez la personnaliser comme

<.>combien de minutes pour actualiser ou accéder. Lorsque le montant atteint un certain montant, actualisez la base de données afin que les données soient exactes et que l'efficacité soit bien supérieure à l'actualisation directe de la base de données à chaque fois

Maintenant que le correspondant la solution est donnée, nous allons commencer à la mettre en œuvre

Prenons comme exemple la navigation d'une publication Nous créons d'abord le contrôleur correspondant


puis générez le modèle que nous devons utiliser
$ php artisan make:controller PostController
Copier après la connexion


Remplissez le contenu du champ de la table de migration des publications
$ php artisan make:model Post -m
Copier après la connexion


Il y a aussi les données de remplissage du Seeder de nos données de tests
Schema::create(&#39;posts&#39;, function (Blueprint $table) {
 $table->increments(&#39;id&#39;);
 $table->string("title");
 $table->string("content");
 $table->integer(&#39;view_count&#39;)->unsigned();
 $table->timestamps();
});
Copier après la connexion


Définir la voie d'accès du poste
$factory->define(App\Post::class, function (Faker\Generator $faker) {
 return [
 &#39;title&#39; => $faker->sentence,
 &#39;content&#39; => $faker->paragraph,
 &#39;view_count&#39; => 0
 ];
});
Copier après la connexion


Bien sûr, nous devons toujours écrire notre accès, qui parcourt l'événement (défini dans app/providers/EventServiceProvider)
Route::get(&#39;/post/{id}&#39;, &#39;PostController@showPost&#39;);
Copier après la connexion


Exécuter la surveillance de la génération d'événements
protected $listen = [
 &#39;App\Events\PostViewEvent&#39; => [
//  &#39;App\Listeners\EventListener&#39;,
  &#39;App\Listeners\PostEventListener&#39;,
 ],
 ];
Copier après la connexion


J'ai déjà défini les méthodes de routage pertinentes et je les implémente maintenant :
$ php artisan event:generate
Copier après la connexion


On peut voir ici que l'utilisation de Redis comme pilote de cache obtiendra également l'objectif IP obtenu. Il s'agit d'empêcher la même IP d'être actualisée plusieurs fois pour augmenter le nombre de vues
public function showPost(Request $request,$id)
{
 //Redis缓存中没有该post,则从数据库中取值,并存入Redis中,该键值key=&#39;post:cache&#39;.$id生命时间5分钟
 $post = Cache::remember(&#39;post:cache:&#39;.$id, $this->cacheExpires, function () use ($id) {
 return Post::whereId($id)->first();
 });

 //获取客户端请求的IP
 $ip = $request->ip();
 
 //触发浏览次数统计时间
 event(new PostViewEvent($post, $ip));

 return view(&#39;posts.show&#39;, compact(&#39;post&#39;));
}
Copier après la connexion

Le. de même chaque navigation déclenchera l'événement que nous avons défini auparavant et passera dans nos paramètres post et id

La dénomination des clés Redis est divisée par : Cela peut être compris comme un répertoire hiérarchique, qui peut être vu clairement dans l'outil de visualisation
La prochaine étape consiste à donner à nos publications le fichier de vue du spectacle

<🎜. >
Initier notre événement c'est recevoir ces paramètres

<html lang="en">
<head>
 <meta charset="utf-8">
 <meta http-equiv="X-UA-Compatible" content="IE=edge">
 <meta name="viewport" content="width=device-width, initial-scale=1">
 <title>Bootstrap Template</title>
 <!-- 新 Bootstrap 核心 CSS 文件 -->
 <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css" rel="external nofollow" >
 <style>
 html,body{
  width: 100%;
  height: 100%;
 }
 *{
  margin: 0;
  border: 0;
 }
 .jumbotron{
  margin-top: 10%;
 }
 .jumbotron>span{
  margin: 10px;
 }
 </style>
</head>
<body>
<p class="container">
 <p class="row">
 <p class="col-xs-12 col-md-12">
  <p class="jumbotron">
  <h1>Title:{{$post->title}}</h1>
  <span class="glyphicon glyphicon-eye-open" aria-hidden="true"> {{$post->view_count}} views</span>
  <p>Content:{{$post->content}}</p>
  </p>
 </p>
 </p>
</p>

<!-- jQuery文件-->
<script src="//cdn.bootcss.com/jquery/1.11.3/jquery.min.js"></script>
<!-- 最新的 Bootstrap 核心 JavaScript 文件 -->
<script src="//cdn.bootcss.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<script>

</script>
</body>
</html>
Copier après la connexion


Le plus important est d'écrire nos événements d'écoute :

class PostViewEvent
{
 use Dispatchable, InteractsWithSockets, SerializesModels;

 public $ip;
 public $post;


 /**
 * PostViewEvent constructor.
 * @param Post $post
 * @param $ip
 */
 public function __construct(Post $post, $ip)
 {
 $this->post = $post;
 $this->ip = $ip;
 }

 /**
 * Get the channels the event should broadcast on.
 *
 * @return Channel|array
 */
 public function broadcastOn()
 {
 return new PrivateChannel(&#39;channel-name&#39;);
 }
}
Copier après la connexion


Enfin, nous pouvons vérifier l'effet spécifique grâce à nos outils

class PostEventListener
{
 /**
 * 一个帖子的最大访问数
 */
 const postViewLimit = 20;

 /**
 * 同一用户浏览同一个帖子的过期时间
 */
 const ipExpireSec = 200;

 /**
 * Create the event listener.
 *
 */
 public function __construct()
 {

 }


 /**
 * @param PostViewEvent $event
 */
 public function handle(PostViewEvent $event)
 {
 $post = $event->post;
 $ip = $event->ip;
 $id = $post->id;
 //首先判断下ipExpireSec = 200秒时间内,同一IP访问多次,仅仅作为1次访问量
 if($this->ipViewLimit($id, $ip)){
  //一个IP在300秒时间内访问第一次时,刷新下该篇post的浏览量
  $this->updateCacheViewCount($id, $ip);
 }
 }

 /**
 * 限制同一IP一段时间内得访问,防止增加无效浏览次数
 * @param $id
 * @param $ip
 * @return bool
 */
 public function ipViewLimit($id, $ip)
 {
 $ipPostViewKey = &#39;post:ip:limit:&#39;.$id;
 //Redis命令SISMEMBER检查集合类型Set中有没有该键,Set集合类型中值都是唯一
 $existsInRedisSet = Redis::command(&#39;SISMEMBER&#39;, [$ipPostViewKey, $ip]);
 //如果集合中不存在这个建 那么新建一个并设置过期时间
 if(!$existsInRedisSet){
  //SADD,集合类型指令,向ipPostViewKey键中加一个值ip
  Redis::command(&#39;SADD&#39;, [$ipPostViewKey, $ip]);
  //并给该键设置生命时间,这里设置300秒,300秒后同一IP访问就当做是新的浏览量了
  Redis::command(&#39;EXPIRE&#39;, [$ipPostViewKey, self::ipExpireSec]);
  return true;
 }
 return false;
 }

 /**
 * 达到要求更新数据库的浏览量
 * @param $id
 * @param $count
 */
 public function updateModelViewCount($id, $count)
 {
 //访问量达到300,再进行一次SQL更新
 $post = Post::find($id);
 $post->view_count += $count;
 $post->save();
 }

 /**
 * 不同用户访问,更新缓存中浏览次数
 * @param $id
 * @param $ip
 */
 public function updateCacheViewCount($id, $ip)
 {
 $cacheKey = &#39;post:view:&#39;.$id;
 //这里以Redis哈希类型存储键,就和数组类似,$cacheKey就类似数组名 如果这个key存在
 if(Redis::command(&#39;HEXISTS&#39;, [$cacheKey, $ip])){
  //哈希类型指令HINCRBY,就是给$cacheKey[$ip]加上一个值,这里一次访问就是1
  $save_count = Redis::command(&#39;HINCRBY&#39;, [$cacheKey, $ip, 1]);
  //redis中这个存储浏览量的值达到30后,就去刷新一次数据库
  if($save_count == self::postViewLimit){
  $this->updateModelViewCount($id, $save_count);
  //本篇post,redis中浏览量刷进MySQL后,就把该篇post的浏览量清空,重新开始计数
  Redis::command(&#39;HDEL&#39;, [$cacheKey, $ip]);
  Redis::command(&#39;DEL&#39;, [&#39;laravel:post:cache:&#39;.$id]);
  }
 }else{
  //哈希类型指令HSET,和数组类似,就像$cacheKey[$ip] = 1;
  Redis::command(&#39;HSET&#39;, [$cacheKey, $ip, &#39;1&#39;]);
 }
 }
}
Copier après la connexion

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!

Étiquettes associées:
source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal