1. 程式人生 > 實用技巧 >php + redis 實現關注功能

php + redis 實現關注功能

產品價值

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
     */
    public function zAddFollow($userId, $otherId)
    {
        $this->redis->zAdd(sprintf($this->prefix . $this->followKey, $userId), time(), $otherId);
    }

    /**
     * 取消關注
     * @param $userId
     * @param $otherId
     */
    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
     */
    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
     */
    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
     */
    public function zAddFans($userId, $otherId)
    {
        $this->redis->zAdd(sprintf($this->prefix . $this->fansKey, $userId), time(), $otherId);
    }

    /**
     * 移除粉絲
     * @param $userId
     * @param $otherId
     */
    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
     */
    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
     */
    public function zRevRangeFans(int $userId, int $start = 0, int $end = 9)
    {
        return $this->redis->zRevRange(sprintf($this->prefix . $this->fansKey, $userId), $start, $end);
    }
}