产品价值

1: 关注功能

2: 功能分析之“关注”功能

3: 平平无奇的「关注」功能,背后有4点重大价值

应用场景

在做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 实现关注功能的更多相关文章

  1. Redis的各项功能解决了哪些问题?

    先看一下Redis是一个什么东西.官方简介解释到:Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用.同时支持string ...

  2. 4个点让你彻底明白Redis的各项功能

    前言 先看一下Redis是一个什么东西.官方简介解释到: Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存中的一个存储系统,你可以把它作为数据库,缓存和消息中间件来使用.同时支持st ...

  3. 【转】Redis的各项功能解决了哪些问题?

    作者:Blackheart 出处:http://linianhui.cnblogs.com 先看一下Redis是一个什么东西.官方简介解释到:Redis是一个基于BSD开源的项目,是一个把结构化的数据 ...

  4. Redis的各项功能解决了哪些问题?(转)

    http://www.cnblogs.com/linianhui/p/what-problem-does-redis-solve.html 先看一下Redis是一个什么东西.官方简介解释到:Redis ...

  5. Redis多机功能介绍

    Redis多机功能目的:以单台Redis服务器过渡到多台Redis服务器 Redis单机在生产环境中存在的问题 1.内存容量不足 Redis使用内存来存书数据库中的数据,但是对于一台机器来说,硬件的内 ...

  6. Redis的事务功能详解

    Redis的事务功能详解 MULTI.EXEC.DISCARD和WATCH命令是Redis事务功能的基础.Redis事务允许在一次单独的步骤中执行一组命令,并且可以保证如下两个重要事项: >Re ...

  7. Redis实现排行榜功能(实战)

    需求前段时间,做了一个世界杯竞猜积分排行榜.对世界杯64场球赛胜负平进行猜测,猜对+1分,错误+0分,一人一场只能猜一次.1.展示前一百名列表.2.展示个人排名(如:张三,您当前的排名106579). ...

  8. Redis实现聊天功能

    在学习了Redis做为消息队列之后研究 了redis聊天的功能. 其实用关系型数据库也可以实现消息功能,自己就曾经用mysql写过一个简单的消息的功能.RDB中思路如下: ** 在实际中可以完全借助m ...

  9. Redis 分析部分功能所解决的问题

    前言:说到缓存,大家都会想到redis,而redis中又有各种眼花缭乱的功能,今天就来看看这些功能能解决的问题. Redis官方简介 Redis是一个基于BSD开源的项目,是一个把结构化的数据放在内存 ...

随机推荐

  1. 虚拟机VMware15 Ubuntu18.04 搭建FTP服务器

    1.安装vsftpd sudo apt install vsftpd 2.查看是否安装成功,出现版本等信息即成功 sudo vsftpd -v 3.添加ftp用户 sudo useradd -m su ...

  2. iOS UIImageView contentMode使用详解

    UIImageView 的contentMode这个属性是用来设置图片的显示方式,如居中.居右,是否缩放等,有以下几个常量可供设定:UIViewContentModeScaleToFill //填满i ...

  3. Error:Execution failed for task ':app:compileDebugAidl'. > java.lang.IllegalStateException: aidl is missing from '/Users/renguodong/Library/Android/sdk/build-tools/26.0.2/aidl'

    错误信息:Error:Execution failed for task ':app:compileDebugAidl'. > java.lang.IllegalStateException: ...

  4. 老猿学5G扫盲贴:R15/R16中计费架构和计费原则涉及的规范文档

    专栏:Python基础教程目录 专栏:使用PyQt开发图形界面Python应用 专栏:PyQt入门学习 老猿Python博文目录 老猿学5G博文目录 一.概述 在R16的32.240文档对应规范为3G ...

  5. PyQt学习随笔:截获窗口Widget组件的关闭事件

    在PyQt中,QWidget类对应基础的窗口组件,如果要在窗口组件关闭时截获关闭事件,提供自己的控制机制,则可以通过在自定义的派生类中重写closeEvent方法. 重写closeEvent方法的语法 ...

  6. 开源版本Visifire的应用

    Visifire曾经开源,保持使用开源版本是不会有版权问题滴. 引用的命名控件 using Visifire.Charts; using Visifire.Commons; 一.应用示例主要代码 // ...

  7. CNVD漏洞证书(1)

    之前申请了CNVD原创漏洞,踩了坑,记录一下 有很多师傅写过相关的文章: https://blog.csdn.net/qq1124794084/article/details/82657840 htt ...

  8. Hive基本原理及配置Mysql作为Hive的默认数据库

    Hive是什么? Hive是基于Hadoop之上的数据仓库: Hive是一种可以存储.查询.分析存储在hadoop中的大规模数据 Hive定义了简单的类SQL查询语言,成为HQL,它允许熟悉SQL的用 ...

  9. .NET 面试题汇总(带答案)

    1.维护数据库的完整性.一致性.你喜欢用触发器还是自写业务逻辑?为什么? 答:尽可能用约束(包括CHECK.主键.唯一键.外键.非空字段)实现,这种方式的效率最好:其次用触发器,这种方式可以保证无论何 ...

  10. 数组的翻转(非reverse)

    var arr = [1, 5, 8, 9, 6, 3]; var arr2 = []; while (arr.length) { var temp = arr.pop(); arr2.push(te ...