Heim > Backend-Entwicklung > PHP-Tutorial > Praktische Anwendungsbeispiele von Redis in Laravel-Projekten

Praktische Anwendungsbeispiele von Redis in Laravel-Projekten

巴扎黑
Freigeben: 2023-03-14 22:16:02
Original
2205 Leute haben es durchsucht

Dieser Artikel führt Sie hauptsächlich in die relevanten Informationen zur Anwendung von Redis im Laravel-Projekt ein. Der Artikel stellt es ausführlich anhand von Beispielcode vor. Es hat einen gewissen Referenz-Lernwert für jeden, der Laravel braucht Es kann weiter unten folgen.

Vorwort

Dieser Artikel stellt Ihnen hauptsächlich die Anwendungsbeispiele von Redis im Laravel-Projekt vor und stellt sie Ihnen als Referenz und zum Studium zur Verfügung Schauen wir uns ohne weitere Umschweife die ausführliche Einführung an:

Nach einem vorläufigen Verständnis der Anwendung von Redis in Laravel stellen wir uns ein solches Anwendungsszenario vor Der Artikel oder Beitrag erhöht sich jedes Mal, wenn ein Seitenaufruf

ein neues Datenelement zur Datenbank hinzufügt. Wenn die Anfrage zu groß ist, ist es selbstverständlich, dass sie die Datenbank verbraucht. Dann können wir andere Lösungen finden

Die Lösung besteht darin, dass Sie bei jedem hinzugefügten Besuch Änderungen im Cache vornehmen, selbst wenn Ihre Website eine große Anzahl von Anfragen hat. Sie können die Aktualisierung der MySQL-Datenbank wie folgt anpassen:

Wie viele Minuten müssen aktualisiert oder aufgerufen werden? Wenn die Menge einen bestimmten Betrag erreicht, aktualisieren Sie die Datenbank, damit die Daten korrekt sind und die Effizienz viel höher ist, als wenn Sie die Datenbank jedes Mal direkt aktualisieren Wenn die Lösung gegeben ist, beginnen wir mit der Umsetzung

Nehmen wir als Beispiel das Durchsuchen eines Beitrags. Wir erstellen zunächst den entsprechenden Controller


und generieren Sie dann das Modell, das wir verwenden müssen
$ php artisan make:controller PostController
Nach dem Login kopieren


Füllen Sie den Feldinhalt der Migrationstabelle der Beiträge aus
$ php artisan make:model Post -m
Nach dem Login kopieren


Es gibt auch die Seeder-Fülldaten unserer Testdaten
Schema::create('posts', function (Blueprint $table) {
 $table->increments('id');
 $table->string("title");
 $table->string("content");
 $table->integer('view_count')->unsigned();
 $table->timestamps();
});
Nach dem Login kopieren


Definieren Sie den Zugangsweg des Pfostens
$factory->define(App\Post::class, function (Faker\Generator $faker) {
 return [
 'title' => $faker->sentence,
 'content' => $faker->paragraph,
 'view_count' => 0
 ];
});
Nach dem Login kopieren


Natürlich müssen wir noch unseren Zugriff schreiben, nämlich das Durchsuchen von Ereignissen (definiert in app/providers/EventServiceProvider)
Route::get('/post/{id}', 'PostController@showPost');
Nach dem Login kopieren


Ereignisgenerierungsüberwachung ausführen
protected $listen = [
 'App\Events\PostViewEvent' => [
//  'App\Listeners\EventListener',
  'App\Listeners\PostEventListener',
 ],
 ];
Nach dem Login kopieren


Ich habe zuvor die relevanten Routing-Methoden definiert und setze sie nun um:
$ php artisan event:generate
Nach dem Login kopieren


Hier ist zu sehen, dass durch die Verwendung von Redis als Cache-Treiber auch die erhaltene IP erhalten wird. Es soll verhindert werden, dass dieselbe IP mehrmals aktualisiert wird, um die Anzahl der Ansichten zu erhöhen
public function showPost(Request $request,$id)
{
 //Redis缓存中没有该post,则从数据库中取值,并存入Redis中,该键值key='post:cache'.$id生命时间5分钟
 $post = Cache::remember('post:cache:'.$id, $this->cacheExpires, function () use ($id) {
 return Post::whereId($id)->first();
 });

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

 return view('posts.show', compact('post'));
}
Nach dem Login kopieren

Dasselbe Jedes Durchsuchen löst das zuvor definierte Ereignis aus und übergibt unsere Post- und ID-Parameter

Die Benennung des Redis-Schlüssels ist unterteilt durch: Dies kann als hierarchisches Verzeichnis verstanden werden, das kann im Visualisierungstool deutlich sichtbar sein
Der nächste Schritt besteht darin, unsere Beiträge anzuzeigen


Um unser Ereignis zu initialisieren, müssen wir diese Parameter erhalten
<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>
Nach dem Login kopieren


Das Wichtigste ist, unsere Hörereignisse zu schreiben:
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;);
 }
}
Nach dem Login kopieren


Endlich können wir die konkrete Wirkung durch unsere Tools überprüfen
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;]);
 }
 }
}
Nach dem Login kopieren

Das obige ist der detaillierte Inhalt vonPraktische Anwendungsbeispiele von Redis in Laravel-Projekten. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
Quelle:php.cn
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage