PHP项目怎么实现资讯置顶推送?

wen PHP项目 51

本文目录导读:

PHP项目怎么实现资讯置顶推送?

  1. 资讯置顶功能
  2. 资讯推送功能
  3. 综合建议(完整流程)
  4. 性能注意点

在PHP项目中实现资讯(文章/新闻)的置顶推送功能,通常涉及数据库设计、业务逻辑处理和后端推送机制。

下面分别给出这两个功能的详细实现方案。


资讯置顶功能

置顶的核心逻辑是:根据一个排序字段,让置顶的资讯永远排在前面

数据库设计

articles 表中增加两个字段:

  • is_top (TINYINT 1):是否置顶,0-否,1-是。
  • top_order (INT 默认0):置顶排序权重,数字越大,排序越靠前(用于处理多条置顶文章的先后顺序)。
-- 示例表结构
CREATE TABLE `articles` (
  `id` int(11) NOT NULL AUTO_INCREMENT, varchar(255) NOT NULL,
  `content` text,
  `created_at` datetime DEFAULT NULL,
  `is_top` tinyint(1) DEFAULT '0' COMMENT '是否置顶 0:否 1:是',
  `top_order` int(11) DEFAULT '0' COMMENT '置顶排序权重',
  PRIMARY KEY (`id`),
  KEY `idx_top` (`is_top`, `top_order`)  -- 联合索引,加速排序查询
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

后台管理(设置置顶)

在管理后台的“资讯编辑”或“列表操作”中,提供一个“设为置顶”的操作。

PHP示例代码(设置置顶逻辑):

<?php
// 假设接收到文章ID和置顶权重
$articleId = $_POST['article_id'];
$topOrder = $_POST['top_order'] ?? 1; // 数字越大越靠前
// 1. 如果只想简单置顶(不分前后),设为1即可
// 2. 如果需要调整顺序,可以让管理员输入数字
$sql = "UPDATE articles SET is_top = 1, top_order = ? WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$topOrder, $articleId]);
// 可选:取消其他文章的置顶(如果只允许一条置顶)
// $sql = "UPDATE articles SET is_top = 0 WHERE id != ?";
// $pdo->prepare($sql)->execute([$articleId]);

取消置顶:

$sql = "UPDATE articles SET is_top = 0, top_order = 0 WHERE id = ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$articleId]);

前端列表查询(排序逻辑)

核心就是 ORDER BY 语句:先按置顶状态排序,再按置顶权重排序,最后按发布时间排序。

PHP示例代码(获取文章列表):

<?php
// 获取文章列表,置顶的永远在前
$sql = "SELECT * FROM articles 
        WHERE status = 1  -- 假设状态为已发布
        ORDER BY 
            is_top DESC,           -- 置顶的排前面 (1 > 0)
            top_order DESC,        -- 置顶的文章中,权重大的排前面
            created_at DESC        -- 非置顶的文章按时间倒序
        LIMIT ? OFFSET ?";
$stmt = $pdo->prepare($sql);
$stmt->execute([$limit, $offset]);
$articles = $stmt->fetchAll();

优化建议:

  • 如果数据量大,可以给 is_top, top_order, created_at 加联合索引。
  • 或者将置顶文章缓存到Redis,查询时先从Redis取置顶列表,再查数据库获取非置顶列表,然后合并。

资讯推送功能

推送是指:当资讯发布或更新时,主动通知用户,实现方式取决于你的应用类型(站内信、小程序、App等)。

这里介绍三种常见场景的实现:

站内信/消息推送(Web端)

适合用户登录网站后看到的“通知中心”。

  • 数据表user_messages (user_id, article_id, type, is_read, created_at)
  • 流程:发布文章 -> 写入 user_messages 表 -> 用户列表页查询。
<?php
// 发布文章成功后,推送站内信
function pushToAllUsers($articleId, $pdo) {
    // 获取所有活跃用户的ID
    $users = $pdo->query("SELECT id FROM users WHERE status = 1")->fetchAll();
    // 批量插入消息(注意:用户量大时需分批,避免SQL过长)
    $sql = "INSERT INTO user_messages (user_id, article_id, type, created_at) VALUES (?, ?, 'article_push', NOW())";
    $stmt = $pdo->prepare($sql);
    foreach ($users as $user) {
        $stmt->execute([$user['id'], $articleId]);
    }
    // 如果是实时推送(WebSocket/SSE),这里可以触发通知
}

WebSocket 实时推送(一般配合 Laravel/PHP Swoole 等)

适合需要即时通知的场景(如后台管理系统、即时聊天)。

  • 方案:使用 Laravel Echo + PusherSwoole WebSocket Server
  • 流程
    1. 发布文章 -> PHP调用Redis发布订阅或直接发消息给WebSocket服务。
    2. WebSocket服务收到消息后,推送给连接到对应房间(如“所有用户”)的客户端。

简单示例(使用 Swoole):

// 1. 创建一个WebSocket服务(单独进程运行)
// 2. 在文章发布API中:
$redis->publish('news_push', json_encode(['article_id' => 123, 'title' => '新资讯']));
// 3. WebSocket Worker 订阅 Redis,收到消息后遍历所有连接并发送

第三方推送(App、小程序)

  • App:集成极光推送、个推、小米推送等SDK,PHP后端调用其服务端API。
  • 小程序:使用微信小程序订阅消息或统一服务消息。
  • 邮件/短信:使用PHPMailer发送邮件,或调用阿里云/腾讯云的短信API。

示例(极光推送):

<?php
// 需要引入极光推送SDK
$client = new \JPush\Client('app_key', 'master_secret');
$push = $client->push();
$push->setPlatform('all')
     ->addAllAudience() // 推送给所有用户
     ->message('资讯标题', [
         'extras' => ['article_id' => 123]
     ])
     ->send();

综合建议(完整流程)

假设你的项目是一个 资讯网站 + 微信公众号/小程序

  1. 后台发布资讯

    • 、正文。
    • 勾选“置顶”,并输入排序权重。
    • 点击“发布并推送”。
  2. 后台PHP处理

    • 写入数据库 articles 表 (is_toptop_order)。
    • 调用 站内信 推送给所有用户(写入 user_messages)。
    • 调用 极光推送微信模板消息 推送到用户手机。
    • 如果用户通过WebSocket在线,则实时推送。
  3. 前端展示

    • 列表页:按 ORDER BY is_top DESC, top_order DESC, created_at DESC 排序。
    • 置顶文章用特殊样式标记(如红色“置顶”标签)。

性能注意点

  1. 置顶:如果置顶文章经常变化,可以缓存置顶ID列表。
    $topIds = $redis->zRevRange('top_articles', 0, -1);
    $normalArticles = $pdo->query("SELECT * FROM articles WHERE id NOT IN (".implode(',', $topIds).") ORDER BY created_at DESC LIMIT 20");
  2. 推送
    • 避免循环发送(如给10万用户发站内信),使用批量INSERT。
    • 异步处理推送任务:将推送请求放入消息队列(Redis、RabbitMQ),后台Worker消费。
  • 置顶:本质是 排序优先级,字段 is_top + top_order + ORDER BY 即可解决。
  • 推送:根据业务场景选型:
    • 简单通知:站内信。
    • 实时:WebSocket。
    • 离线/移动:第三方推送服务。

如果你的项目已经是一个成熟的框架(如 Laravel、ThinkPHP),可以查看其事件系统(Events + Listeners)或队列(Queue),将推送逻辑解耦,提高响应速度。

抱歉,评论功能暂时关闭!