php + redis 实现关注功能
产品价值
应用场景
在做PC或者APP端时,掺杂点社交概念就有关注和粉丝功能;
数据量小的话数据库还能支持,如果数据量很庞大还是用缓存比较好。
具体实现
1 控制层实现
/**
* 关注/取消关注
* @param Request $request
* @return mixed
*/
public function follow(Request $request)
{
$type = $request->input('type', 'follow'); // 1-关注-follow 2-取消关注-remove
$userId = $request->input('user_id', 0); // 我的用户ID
$otherId = $request->input('other_id', 0); // 我关注的用户ID
if ($userId == $otherId) {
return $this->response->apiResponse();
}
$this->testFollowService->follow($type, $userId, $otherId);
return $this->response->apiResponse();
}
/**
* 我的关注/粉丝
* @param Request $request
* @return mixed
*/
public function myFollowAndFans(Request $request)
{
$type = $request->input('type', 'follow'); // 1-关注-follow 2-粉丝-fans
$userId = $request->input('user_id', 0); // 我的用户ID
$page = $request->input('page', 1); // 页码
$limit = $request->input('limit', 10); // 每页显示条数
$res = $this->testFollowService->myFollowAndFans($userId, $type, $page, $limit);
return $this->response->apiResponse($res);
}
2 服务层实现
/**
* 关注/取消关注
* @param string $type
* @param int $userId
* @param int $otherId
* @return mixed
*/
public function follow($type = 'follow', int $userId, int $otherId)
{
// 关注
if ($type === 'follow') {
$this->testFollowRedis->zAddFollow($userId, $otherId);
$this->testFollowRedis->zAddFans($otherId, $userId);
}
// 取消关注
if ($type === 'remove') {
$this->testFollowRedis->zRemFollow($userId, $otherId);
$this->testFollowRedis->zRemFans($otherId, $userId);
}
}
/**
* 我的关注/粉丝
* @param int $userId 当前登录用户的ID
* @param string $type 要获取的数据
* @param int $page 页码
* @param int $limit 限制条数
* @return array
*/
public function myFollowAndFans(int $userId, $type = 'follow', $page = 1, $limit = 10)
{
$start = $limit * ($page - 1);
$end = $start + $limit - 1;
$res = [];
if ($type === 'follow') {
$res = $this->testFollowRedis->zRangeFollow($userId, $start, $end);
}
if ($type === 'fans') {
$res = $this->testFollowRedis->zRangeFans($userId, $start, $end);
}
return $res;
}
仓储层实现
<?php
namespace App\Repository\Redis;
class TestFollowRedis extends AbstractRedis
{
/**
* 关注key
* @var string
*/
private $followKey = '%u:follow';
/**
* 粉丝key
* @var string
*/
private $fansKey = '%u:fans';
/**
* 前缀
*/
public function initPrefix()
{
return 'follow:';
}
/**
* 增加关注
* @param $userId
* @param $otherId
* @author ptg 2020/12/9 5:55 下午
*/
public function zAddFollow($userId, $otherId)
{
$this->redis->zAdd(sprintf($this->prefix . $this->followKey, $userId), time(), $otherId);
}
/**
* 取消关注
* @param $userId
* @param $otherId
* @author ptg 2020/12/9 5:55 下午
*/
public function zRemFollow($userId, $otherId)
{
$this->redis->zRem(sprintf($this->prefix . $this->followKey, $userId), $otherId);
}
/**
* 我的关注 | 正序
* @param int $userId
* @param int $start
* @param int $end
* @return array
* @author ptg 2020/12/9 7:57 下午
*/
public function zRangeFollow(int $userId, int $start = 0, int $end = 9)
{
return $this->redis->zRange(sprintf($this->prefix . $this->followKey, $userId), $start, $end);
}
/**
* 我的关注 | 倒序
* @param int $userId
* @param int $start
* @param int $end
* @return array
* @author ptg 2020/12/9 7:57 下午
*/
public function zRevRangeFollow(int $userId, int $start = 0, int $end = 9)
{
return $this->redis->zRevRange(sprintf($this->prefix . $this->followKey, $userId), $start, $end);
}
/**
* 增加粉丝
* @param $userId
* @param $otherId
* @author ptg 2020/12/9 6:27 下午
*/
public function zAddFans($userId, $otherId)
{
$this->redis->zAdd(sprintf($this->prefix . $this->fansKey, $userId), time(), $otherId);
}
/**
* 移除粉丝
* @param $userId
* @param $otherId
* @author ptg 2020/12/9 6:27 下午
*/
public function zRemFans($userId, $otherId)
{
$this->redis->zRem(sprintf($this->prefix . $this->fansKey, $userId), $otherId);
}
/**
* 我的粉丝 | 正序
* @param int $userId
* @param int $start
* @param int $end
* @return array
* @author ptg 2020/12/9 7:56 下午
*/
public function zRangeFans(int $userId, int $start = 0, int $end = 9)
{
return $this->redis->zRange(sprintf($this->prefix . $this->fansKey, $userId), $start, $end);
}
/**
* 我的粉丝 | 倒序
* @param int $userId
* @param int $start
* @param int $end
* @return array
* @author ptg 2020/12/9 7:56 下午
*/
public function zRevRangeFans(int $userId, int $start = 0, int $end = 9)
{
return $this->redis->zRevRange(sprintf($this->prefix . $this->fansKey, $userId), $start, $end);
}
}
php + redis 实现关注功能的更多相关文章
- Redis的各项功能解决了哪些问题?
先看一下Redis是一个什么东西.官方简介解释到:Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用.同时支持string ...
- 4个点让你彻底明白Redis的各项功能
前言 先看一下Redis是一个什么东西.官方简介解释到: Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用.同时支持st ...
- 【转】Redis的各项功能解决了哪些问题?
作者:Blackheart 出处:http://linianhui.cnblogs.com 先看一下Redis是一个什么东西.官方简介解释到:Redis是一个基于BSD开源的项目,是一个把结构化的数据 ...
- Redis的各项功能解决了哪些问题?(转)
http://www.cnblogs.com/linianhui/p/what-problem-does-redis-solve.html 先看一下Redis是一个什么东西.官方简介解释到:Redis ...
- Redis多机功能介绍
Redis多机功能目的:以单台Redis服务器过渡到多台Redis服务器 Redis单机在生产环境中存在的问题 1.内存容量不足 Redis使用内存来存书数据库中的数据,但是对于一台机器来说,硬件的内 ...
- Redis的事务功能详解
Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础.Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >Re ...
- Redis实现排行榜功能(实战)
需求前段时间,做了一个世界杯竞猜积分排行榜.对世界杯64场球赛胜负平进行猜测,猜对+1分,错误+0分,一人一场只能猜一次.1.展示前一百名列表.2.展示个人排名(如:张三,您当前的排名106579). ...
- Redis实现聊天功能
在学习了Redis做为消息队列之后研究 了redis聊天的功能. 其实用关系型数据库也可以实现消息功能,自己就曾经用mysql写过一个简单的消息的功能.RDB中思路如下: ** 在实际中可以完全借助m ...
- Redis 分析部分功能所解决的问题
前言:说到缓存,大家都会想到redis,而redis中又有各种眼花缭乱的功能,今天就来看看这些功能能解决的问题. Redis官方简介 Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存 ...
随机推荐
- D - Number of Multisets 题解(思维dp)
题目链接 题目大意 给你一个数k和n,表示用n个\(1/2^i(i=0,1,2.....)\)组成k有多少种方案数 题目思路 这个dp实属巧妙 设\(dp[i][j]表示i个数构成j\) 这i个数可以 ...
- Django中ModelForm详解
1.ModelForm组件介绍:这个组件的功能就是把model和form组合起来 2.ModelForm的使用 1.首先需要导入ModelForm from django.forms import M ...
- 磁盘冗余阵列之RAID5、RAID10
RAID技术主要有以下三个基本功能: (1).通过对磁盘上的数据进行条带化,实现对数据成块存取,减少磁盘的机械寻道时间,提高了数据存取速度. (2).通过对一个阵列中的几块磁盘同时读取,减少了磁盘的机 ...
- SQL优化思路与解决方案
1.面对问题SQL的思考 这条查询SQL的语句到底有没有问题? 存在什么问题? 什么情况下存在问题? 怎么去优化? 2.SQL优化思路 where查询字段是否建立索引? 是否有建立索引但是查询时候没有 ...
- Prometheus 使用之 node exporter
本文使用的 Prometheus 版本为 2.22.0,node exporter 版本为 1.0.1:部署在 Linux 服务器Prometheus 是开源的监控报警系统和时序列数据库 (TSDB) ...
- 老猿学5G扫盲贴:中国移动网络侧CHF主要功能及计费处理的主要过程
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt+moviepy音视频剪辑实战 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一. ...
- moviepy简介及安装
专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 MoviePy是一个用于视频编辑的Pyt ...
- PyQt(Python+Qt)学习随笔:Designer中的QDialogButtonBox的orientation和centerButtons属性
orientation属性 orientation属性表示QDialogButtonBox的方向,缺省情况下,方向为水平方向(值为Qt.Horizontal),表示QDialogButtonBox中的 ...
- pandas 由其中几列生成新的列
data是一个dataframe #data["x1"]=data[["a","b"]].apply(lambda x:x["a& ...
- ASP.NET Log4net数据库日志新增记录客户端ip
LOG4数据库记录器XML配置 1 <appender name="ADONetAppender" type="log4net.Appender.ADONetApp ...