php+redis实现点赞功能
首先设计redis
1、设计一个set结构的article存储被点赞的article_id
2、设计set结构的article_like_{article_id}里面存储点赞该文章的用户
3、设计一个hash结构的article_user_like_{article_id}__{user_id}存储用户点赞的详细信息
4、设计一个string结构的article_id_count存储文章的点赞总数
下面是我使用CI框架实现的具体功能代码:
这里我目前只使用了redis实现,后续会实现redis以及mysql的实现。这里使用的redis方法是之前封装的redis单例类。
common_helper文件中有一个获取redis单例的方法
/*
* 加载libraries
*/
if (!function_exists('require_class')) {
function require_class($name)
{
require_once('application' . DIRECTORY_SEPARATOR . 'libraries' . DIRECTORY_SEPARATOR . $name . '.php');
}
}
/*
* 获取redis连接
*/
if (!function_exists('getRedis')) {
function getRedis()
{
require_class('RedisCurd');
return RedisCurd::getInstance();
}
}
控制器代码,这里点击一次该接口为点赞,再次点击则会取消点赞,且一个用户只可以为一篇文章点一次赞。
/*
* 文章点赞/取消点赞
*/
public function fabulous()
{
$data = $this->input->post();
if (empty($data['user_id'])) {
fail('400', '点赞异常!');
}
if (empty($data['article_id'])) {
fail('400', '点赞异常!');
}
//set类型存储全部点赞的文章
$conn = getRedis();
$conn->selectDb(0);
$key1 = "like_article";
//该文章是否已经在set中
if (!$conn->sisMember($key1, $data['article_id'])) {
$conn->sAdd($key1, $data['article_id']);
}
//set类型存储点赞文章的用户id
$key2 = "user_like" . $data['article_id'];
//该文章是否已经被该用户点赞
$status = $conn->sisMember($key2, $data['user_id']);
//hash类型存储点赞的详细信息
$key3 = $data['user_id'] . "_like_" . $data['article_id'];
if (!$status) {
$conn->sAdd($key2, $data['user_id']);
$res = [
'user_id' => $data['user_id'],
'article_id' => $data['article_id'],
'create_time' => time()
];
$conn->hMSet($key3, $res);
}
//存储文章点赞总数
$key4 = "article_" . $data['article_id'] . "_count";
//若该用户未给该文章点赞
if (!$status) {
$conn->incr($key4);
} else {
//已经点赞了删除hash集合
$conn->del($key3);
$conn->del($key2);
$conn->decr($key4);
}
//点赞总数
$res = $conn->get($key4);
success($res, '点赞成功!');
}
使用postman调用接口查看点赞结果
这里从redis的客户端查看是否存在前面设置的redis的key
再次点击运行结果
这里已经没有hash和存储点赞文章的用户id的set了。文章点赞总数的set也变成0了。