使用Laravel和Redis制作浏览次数排行榜
首先
我在Laravel项目中使用redis实现了类似于在许多网站上看到的”热门文章”功能。我将其中一部分样例代码分享出来。
以下是示例代码:https://github.com/esuEichi/sample_view_ranking_with_laravel_redis.git
当您只想快速查看操作时,您可以先克隆上述示例代码,然后执行 composer install 和 composer update。接下来,按照底部所示的步骤进行操作确认。
这次的学习经历
-
- redis はキーバリューなので、基本的に一意の値で表現できるのは一つ
categoryと投稿日でランキングを作るなどのときはkeyの値を工夫する必要がある
为难的事情 (Kuratta koto)
- 今回作成したRankingModluleをControllerとして作っていますが、MVCとしてのControllerの役割は持っていないため、なんとなく気持ち悪い
思维方式
-
- 記事IDをもとに一意なredisのキーを作成する
-
- 表示のためのController が呼ばれたときredisにキーがあるかを確認する
なければvalue1にセット
あればvalueをインクリメント
キーから記事IDとビュー数を持った配列を作る
value順にソートしてviewへ渡す
viewでforeachで出力する
步驟
创建项目
使用composer命令创建一个名为sample_ranking_with_redis的项目,该项目的基础框架为laravel/laravel。
在composer中安装redis
请按照以下方式向composer.json文件中添加predis库。
"require": {
"php": ">=5.6.4",
"laravel/framework": "5.4.*",
"laravel/tinker": "~1.0",
"predis/predis":"^1.1"
},
追加完毕后,使用以下命令可以使用redis。
安装composer
更新composer
启动Redis
用以下的命令启动Redis。非常简单。
路由/网络的重写
默认的top路径被注释掉,并添加以下两行。
基本上,在转到top时,通过Controller进行传递。
在转到文章页面(LinkView)时,也通过Controller进行传递。同时也要确保在Controller中接收到文章的ID。
Route::get('/', 'TopController@index');
Route::get('/{id}','LinkController@index');
创建排名功能所需的文件
创建排名模块
本次将创建一个负责核心排名部分的模块。
首先,使用以下命令创建一个名为Controller的模块。
php artisan make:controller RankingModule
提供以下两种方法。
增加_view_ranking方法
当被用户查看文章页面时,调用该方法来增加浏览次数。通过接受ID作为参数,调用者将是linkController。
获取所有排名的方法
这是一个按排名返回结果的方法。它从Redis中获取所有键,并按值进行排序后返回数组。调用者是TopController。方法的具体实现如下:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Redis;
class RankingModule extends Controller
{
//
public function increment_view_ranking($id){
$key = "ranking-"."id:".$id;
$value = Redis::get($key);
if(empty($value)){
Redis::set($key, "1");
Redis::expire($key, 60*60);
} else {
Redis::set($key,$value + 1);
}
echo "view count:".Redis::get($key);
}
public function get_ranking_all(){
$keys = Redis::keys('ranking-*');
$results = Array();
if(empty($keys) != true){
for($i=0; $i < sizeof($keys); $i++){
$point = Redis::get($keys[$i]);
$id = explode(':', $keys[$i])[1];
$results[$id] = $point;
}
arsort($results, SORT_NUMERIC);
}
return $results;
}
}
创建链接视图
这次只是复制粘贴和重命名了默认的欢迎模板。
创建LinkController
这是一个执行从上面创建链接的转移的控制器。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class LinkController extends Controller
{
//
function index(Request $request){
$id = $request->id;
$ranking = new RankingModule;
$ranking->increment_view_ranking($id);
return view('link')->with(compact('id'));
}
}
welocome viewに記事へのリンク先を作成し、ランキングを作成する
创建TopController
route/web.phpで書き換えたように、Topページ(welcomeView)への遷移を司るコントローラーです。
役割としてはRankingModuleから現在のランキング表示用の配列を作成し、
viewへ渡すことです。
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
class TopController extends Controller
{
//
function index(Request $request){
$ranking = new RankingModule;
$results = $ranking->get_ranking_all();
return view('welcome')->with(compact('results'));
}
}
欢迎您来到Welcomeview的更改
在欢迎页(topページ)上创建链接。
文章链接
我們會創建從主頁可以轉到假資訊文章頁面的連結。
這次是假的,所以我們會用for迴圈創建10個文章連結,每個連結都有不同的ID指向不同的文章。
排行榜的制作
使用从TopController接收到的排名结果数组,将链接创建到浏览量最多的相关文章。顺便将浏览次数显示在链接中。还会使用dump命令把排名用的数组输出。
3d2
<
85,94c84,90
< <div class="test_links">
< @for ($i = 0; $i < 10; $i++)
< <div><a href="./{{{$i}}}">link_{{{$i}}}</a></div>
< @endfor
< </div>
< <div class="ranking">
< @foreach($results as $id => $point)
< <div><a href="./{{{$id}}}">link_{{{$id}}}_view_count_is_{{{$point}}}</a></div>
< @endforeach
< <?php var_dump($results);?>
答案
请运行以下两个命令:
php artisan serve
redis-server
http://localhost:8000
へアクセス
http://localhost:8000/1
などのページを見ると、一番下の順番が変わっていきます。

关于扩展性
当想要创建按特定类别或条件进行排名的情况下
redis的键如下所示。
$key = “ranking-“.”id:”.$id;
例如,如果有多个类别,并且想要在/category页面上创建下级内容的排名,首先需要将键设置为以下方式。
$key = “排名-“.”id:”.$id.”_分类:”.$category;
通过在类别中获取关键字,可以创建不仅仅是整体排名,还包括类别排名的排行榜。
结束
在实际服务中,我们进行了更多的扩展,使用了按类别排名和整体排名的扩展性。通过创建排名,即使是小型服务,也能感受到用户的使用,并变得更加有趣。
填補
我从niisan-tokyo先生那里得到了一个关于使用Redis的有序集合功能的建议。详细内容请参考以下文章:http://qiita.com/niisan-tokyo/items/170ef3ac47ee39cfb46c
如果像这次一样,需要无限期并持续引用相同的键值,这个选项似乎更好,而且计算成本也较低。
谢谢您的指正。