Redis+PHP實現(xiàn)用戶消息推送每天最多通知2次的功能
一、背景
在開發(fā)應(yīng)用程序中,經(jīng)常需要向用戶推送消息通知,但是為了避免過多的打擾用戶,我們希望限制每天最多通知2次。本文將介紹如何使用 PHP 和 Redis 實現(xiàn)這一功能。
二、準備工作
首先,我們需要準備好數(shù)據(jù)庫和 Redis 服務(wù)。在 MySQL 數(shù)據(jù)庫中創(chuàng)建一個 user_notifications
表, 包含以下字段:
id
:主鍵自增長IDuser_id
:用戶IDcontent
:通知內(nèi)容created_at
:記錄創(chuàng)建時間
此外,還需要安裝 Redis 擴展,在 PHP 中可以通過以下命令安裝:
$ pecl install redis
常見的推送消息場景如下圖。
三、實現(xiàn)邏輯
3.1 查詢用戶的已發(fā)送通知數(shù)量
在用戶登錄或接收新通知時,我們需要查詢用戶今天已發(fā)送的通知數(shù)量。我們可以利用 Redis 的 Sorted Set 數(shù)據(jù)結(jié)構(gòu)來存儲每個用戶的通知記錄。將用戶ID作為 Sorted Set 的 key,通知的發(fā)送時間戳作為 score 值,這樣就可以按照時間順序存儲用戶的通知記錄。
使用以下代碼實現(xiàn)查詢用戶已發(fā)送通知數(shù)量的函數(shù):
function getNotificationCount($userId) { $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $todayStart = strtotime('today'); // 當(dāng)天開始的時間戳 $todayEnd = strtotime('tomorrow') - 1; // 當(dāng)天結(jié)束的時間戳 $count = $redis->zcount('user_notifications:' . $userId, $todayStart, $todayEnd); return $count; }
3.2 發(fā)送通知
在發(fā)送通知之前,先檢查用戶已發(fā)送通知數(shù)量是否達到限制。如果已發(fā)送通知數(shù)量大于等于2,則不再發(fā)送新通知;否則,保存通知記錄到數(shù)據(jù)庫,并將通知記錄的發(fā)送時間戳添加到 Redis Sorted Set 中。
使用以下代碼實現(xiàn)發(fā)送通知的函數(shù):
function sendNotification($userId, $content) { // 檢查用戶已發(fā)送通知數(shù)量 $count = getNotificationCount($userId); if ($count >= 2) { return false; } // 保存通知記錄到數(shù)據(jù)庫 $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password'); $stmt = $pdo->prepare("INSERT INTO user_notifications (user_id, content, created_at) VALUES (?, ?, NOW())"); $stmt->execute([$userId, $content]); // 將通知記錄的發(fā)送時間戳添加到 Redis Sorted Set $redis = new Redis(); $redis->connect('127.0.0.1', 6379); $redis->zadd('user_notifications:' . $userId, time(), $content); return true; }
3.3 獲取用戶通知列表
用戶可以通過接口或頁面查看自己的通知列表。我們可以從數(shù)據(jù)庫中查詢用戶的通知記錄,并按照發(fā)送時間倒序排列。
使用以下代碼實現(xiàn)獲取用戶通知列表的函數(shù):
function getNotificationList($userId) { $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password'); $stmt = $pdo->prepare("SELECT * FROM user_notifications WHERE user_id = ? ORDER BY created_at DESC"); $stmt->execute([$userId]); $notifications = $stmt->fetchAll(PDO::FETCH_ASSOC); return $notifications; }
3.4 清理過期通知記錄
為了避免 Redis Sorted Set 中存儲的用戶通知記錄過多,我們可以定時清理過期的通知記錄。通過設(shè)置 Redis 的過期時間來實現(xiàn)自動清理。例如,我們可以設(shè)置 Sorted Set 的過期時間為2天,在用戶查詢通知列表時,先刪除過期的通知記錄,再返回有效的通知列表。
function cleanExpiredNotifications($userId) { $redis = new Redis(); $redis->connect('127.0.0.1', 6379); // 設(shè)置 Sorted Set 的過期時間為2天 $expireTime = strtotime('2 days ago'); $redis->expireAt('user_notifications:' . $userId, $expireTime); }
3.5 定時任務(wù)
為了每天凌晨清理用戶的通知記錄,我們可以使用 Linux 的 crontab 來定時執(zhí)行清理任務(wù)。編輯 crontab 文件,添加如下代碼:
0 0 * * * php /path/to/clean_expired_notifications.php
并創(chuàng)建 clean_expired_notifications.php
文件,內(nèi)容如下:
<?php require_once 'redis.php'; $pdo = new PDO('mysql:host=localhost;dbname=test', 'username', 'password'); $stmt = $pdo->prepare("SELECT DISTINCT user_id FROM user_notifications"); $stmt->execute(); $userIds = $stmt->fetchAll(PDO::FETCH_COLUMN); foreach ($userIds as $userId) { cleanExpiredNotifications($userId); }
四、結(jié)語
通過 PHP 和 Redis 實現(xiàn)用戶消息推送每天最多通知2次的功能,并結(jié)合定時任務(wù)清理過期通知記錄,可以有效地避免過多地打擾用戶。以上是基本實現(xiàn)邏輯和代碼示例,你可以根據(jù)自己的實際需求進行修改和擴展,例如根據(jù)不同用戶設(shè)置不同的通知限制次數(shù)等。
以上就是Redis+PHP實現(xiàn)用戶消息推送每天最多通知2次的功能的詳細內(nèi)容,更多關(guān)于Redis實現(xiàn)用戶消息推送的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
redis-cli登錄遠程redis服務(wù)并批量導(dǎo)入數(shù)據(jù)
本文主要介紹了redis-cli登錄遠程redis服務(wù)并批量導(dǎo)入數(shù)據(jù),文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-10-10Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例
本文主要介紹了 Redis遍歷海量數(shù)據(jù)的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2025-04-04基于Redis緩存數(shù)據(jù)常見的三種問題及解決
這篇文章主要介紹了基于Redis緩存數(shù)據(jù)常見的三種問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-06-06淺析對redis?hashtable?的sizemask理解
在?Redis?的哈希表實現(xiàn)中,index?=?hash?&?dict->ht[0].sizemask?是計算鍵值對應(yīng)存儲位置的核心操作,本文給大家介紹redis?hashtable?的sizemask理解,感興趣的朋友一起看看吧2025-03-03