読者です 読者をやめる 読者になる 読者になる

備忘録

開発の日々の備忘録

phpredisでデイリーランキング


redisのソート済みセット型を使えば簡単にランキングが実装できるらしい
勉強がてらやってみた

phpredisのセットアップはこっちを参考に

eeggs.hatenablog.com

環境


  • redis 3.0.7
  • php 7.0.3
  • phpredis

やること


  • JSONで日付、ユーザーID、スコアを受け取る
    • 例 {"date":"2016-02-28","id":2,"score":999}
  • JSONで順位、参加人数を返却
    • 例 {"rank":200,"total":10000}

いざ!


Ranking.php

<?php
$json  = file_get_contents('php://input');
$obj   = json_decode( $json );
$date  = $obj->{'date'};
$id    = $obj->{'id'};
$score = $obj->{'score'};

/*バリデーションは割愛*/

//Redisへ接続
$redis = new Redis();
$redis->connect("127.0.0.1",6379);

//ユーザー追加&ランキング更新(日付をKeyにする)
$redis->zAdd($date,$score,$id);

//該当日の要素数取得
$total = $redis->zCard($date);

//スコアを降順に並べて、自分の順位を取得
$rank = $redis->zRevRank($date, $id);

//0番目から順に順位が振られるのでインクリメント
$rank++;

//結果をJSONで返却
header('Content-type: application/json');
echo json_encode(array('rank'=>$rank,'total'=>$total));

テスト


idやscoreを変えながらJSONをPOSTしてみる

$ curl -H "Content-type: application/json" -X POST -d '{"date":"2016-02-28","id":1,"score":100}' http://localhost/Ranking.php
{"rank":1,"total":1}

$ curl -H "Content-type: application/json" -X POST -d '{"date":"2016-02-28","id":2,"score":1000}' http://localhost/Ranking.php
{"rank":1,"total":2}

$ curl -H "Content-type: application/json" -X POST -d '{"date":"2016-02-28","id":3,"score":10}' http://localhost/Ranking.php
{"rank":3,"total":3}

$ curl -H "Content-type: application/json" -X POST -d '{"date":"2016-02-28","id":1,"score":1001}' http://localhost/Ranking.php
{"rank":1,"total":3}

とりあえず問題なさそう

懸念点


同点ユーザーがいた場合に同じ順位とならないので、同着を取りたければ一手間加える必要がある
自分より高いスコアのユーザー数を抽出して+1するのが一般的??