1.需求
1.首先设计数据库
2.代码
Redis.php
<?php
//评分是将文章的到的支持票数乘以一个常量,然后加上文章的发布时间,得出的结果就是文章的评分
const ONE_WEEKS_IN_SECONDS = 7*86400;
//常量是通过一天的秒数(86400)除以文章展示一天所需的支持票数(200)的出的
const VOTE_SCORE = 432;
class Redis1{
private static $instance;
// private function __construct(){} //私有构造,不允许new
private function __clone(){} //私有克隆方法,不允许通过魔术方法克隆对象
public function getIntance($host="127.0.0.1",$port="6379")
{
if (!self::$instance instanceof self)
{
self::$instance = new Redis();
self::$instance->connect($host,$port);
}
$myredis = self::$instance;
return $myredis;
}
public function index()
{
echo "hello world";
}
/**
* 对文章进行投票
* @param $myredis
* @param $user
* @param $article_id
* @return bool
*/
public function article_vote()
{
$redis = $this->getIntance();
$article = 'article:24';
$user = 8;
$cutoff = time() - ONE_WEEKS_IN_SECONDS; //计算文章投票截止时间
if ($redis->zScore('time:',$article) < $cutoff) //检测是否可以对文章进行投票
{
return false;
}
$end = strpos($article,'article:');
$article_id = substr($article,strlen('article:')+$end) ;//从article:id中提取文章的id
//echo $article_id;die();
//如果用户是第一次为这篇文章进行投票,那么增加这篇文章的投票数量和评分
$first = $redis->sadd('voted:'.$article_id,$user);
echo 'first';echo $first.'<br>';
if ($first)
{
$score = $redis->zIncrBy('score:',VOTE_SCORE,$article); //集合添加 给这篇文章加分
echo "score".$score;
$vote = $redis->hIncrBy($article,'votes',1); //hash添加 给这篇文章阅读人数+1
echo "<br>vote".$vote;
if ($score && $vote)
{
echo "添加成功0";
}else{
echo "添加失败0";
}
}else{
echo "添加失败1";
}
}
/**
* 文章发布功能
* @param $myredis
* @param $user
* @param $title
* @param $link
* @return string
*/
public function post_article()
{
//模拟数据
$user_id = 1;
$title = "文章标题1";
$link = "http://www.baidu.com";
$redis = $this->getIntance();
$article_id = $redis->incr('article:'); //生成一个新的文章id
$voted = 'voted:'.$article_id;
$redis->sAdd($voted,$user_id); //将发布文章的用户添加到文章的已投票用户名单里面,
$redis->expire($voted,ONE_WEEKS_IN_SECONDS); //然后将这个名单的过期时间设置为一周
$article = 'article:'.$article_id;
$result = $redis->hMset($article,[ //将文章的信息存到一个散列里面
'title'=>$title,
'link'=>$link,
'poster'=>$user_id,
'time'=>time(),
'votes'=>1
]);
echo $article;
$score = $redis->zAdd('score:',time()+VOTE_SCORE,$article); //将文章添加到根据评分顺序的有序集合里面
$time = $redis->zAdd('time:',time(),$article); //将文章添加根据发布时间排序的有序集合和里面
if ($result && $score && $time)
{
echo $article."文章创建成功";exit();
}else{
echo $article_id."文章创建失败";exit();
}
return $article_id;
}
/**
* 文章获取功能
* @param $conn
* @param $page
* @param string $order
* @return array
*/
public function get_articles()
{
//$page = $_POST['page']?$_POST['page']:1;
$page = 1;
$order="score:";
$redis = $this->getIntance();
$ARTICLE_PER_PAGE = 25;
$start = ($page-1) * $ARTICLE_PER_PAGE; //设置获取文章的起始索引和结束索引
$end = $start+ $ARTICLE_PER_PAGE-1;
$ids = $redis->zRange($order,$start,$end); //获取多个文章的id
//var_dump($ids);die();
$articles = [];
foreach ($ids as $id) //根据文章id获取文章详细信息
{
$article_data = $redis->hGetAll($id);
$article_data['id'] = $id;
$articles[] = $article_data;
}
var_dump($articles);die();
return $articles;
}
/**
* 对文章进行分组
* @param $conn
* @param $article_id
* @param $toadd
* @param $toremove
*/
public function add_remove_groups()
{
$redis = $this->getIntance();
$article_id = 23;
$toadd = [1,2,3];
$toremove = [1];
$article = 'article:'.$article_id; //构建存储文章信息的键名
foreach ($toadd as $group)
{
$redis->sadd('group:'.$group,$article); //将文章添加到他所属的群组里面
}
foreach ($toremove as $group)
{
$redis->srem('group:'.$group,$article); //从群组里面移除文章
}
echo "分组成功";
}
/**
* 分页获取文章数据
* @param $conn
* @param $group
* @param $page
* @param string $order
* @return array
*/
public function get_group_articles()
{
$redis = $this->getIntance();
$order="score:";
$group = 1;
$page =1;
$key = $order.$group; //为每个群组的每种排列顺序都创建一个键
if (!$redis->exists($key)) //检测是否有已缓存的排序结果,如果没有的话现在就进行排序
{
$redis->zinterstore($key,
['group:'.$group,$order]
/*['aggregate'=>'max']*/); //根据评分或者发布时间对群组文章进行排序
}
$redis->expire($key,60); //让redis60s之后自动删除这个有序集合
return $this->get_articles($redis,$page,$key);
}
}
$myredis = new Redis1();
//$myredis->index();
//$myredis->post_article();
//$myredis->get_articles();
//$myredis->article_vote();
//$myredis->add_remove_groups();
$myredis->get_group_articles();
3.待解决问题
1.文章分组(交集和并集)
2.zinterstore的用法