PHP项目如何实现逾期提醒?

wen java案例 3

本文目录导读:

PHP项目如何实现逾期提醒?

  1. 数据库设计(核心字段)
  2. 方案一:Cron Job + PHP脚本(最可靠)
  3. 方案二:使用Laravel的任务调度
  4. 提醒方式实现
  5. 方案三:实时提醒(WebSocket + 事件驱动)
  6. 防重复提醒策略
  7. 监控与日志

在PHP项目中实现逾期提醒功能,通常需要结合任务调度(Cron Job)定时消息推送数据库状态管理,以下是一个完整的实现方案:


数据库设计(核心字段)

假设你有 orders 表(订单),需要记录到期时间:

CREATE TABLE orders (
    id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT,
    due_date DATETIME NOT NULL,          -- 截止日期
    status ENUM('active', 'overdue') DEFAULT 'active',
    remind_at DATETIME NULL,             -- 上次提醒时间(防止重复提醒)
    ...
);

方案一:Cron Job + PHP脚本(最可靠)

步骤:

  1. 编写PHP检查脚本 (cron_check_overdue.php)
  2. 设置系统定时任务(Linux的cron)

PHP脚本示例:

<?php
// 连接数据库
$pdo = new PDO('mysql:host=localhost;dbname=test', 'user', 'pass');
// 查找所有逾期且未提醒的记录
$sql = "SELECT * FROM orders 
        WHERE due_date < NOW() 
        AND status = 'active' 
        AND (remind_at IS NULL OR remind_at < DATE_SUB(NOW(), INTERVAL 1 HOUR))";
$stmt = $pdo->query($sql);
$orders = $stmt->fetchAll();
foreach ($orders as $order) {
    // 1. 发送提醒(邮件/短信/系统通知)
    sendReminder($order['user_id'], $order['id']);
    // 2. 更新状态为逾期,并记录提醒时间
    $update = $pdo->prepare("UPDATE orders 
                            SET status = 'overdue', 
                                remind_at = NOW() 
                            WHERE id = ?");
    $update->execute([$order['id']]);
}
echo "Checked " . count($orders) . " overdue orders.";
?>

Cron配置(每分钟运行一次):

* * * * * /usr/bin/php /path/to/cron_check_overdue.php >> /var/log/overdue.log 2>&1

方案二:使用Laravel的任务调度

如果你使用Laravel框架,可以更优雅地实现:

app/Console/Kernel.php 中定义:

protected function schedule(Schedule $schedule)
{
    $schedule->call(function () {
        // 查询逾期订单
        $overdueOrders = Order::where('due_date', '<', now())
                              ->where('status', 'active')
                              ->get();
        foreach ($overdueOrders as $order) {
            // 发送提醒
            $order->user->notify(new OverdueReminder($order));
            $order->update(['status' => 'overdue', 'remind_at' => now()]);
        }
    })->everyMinute();  // 或 dailyAt('08:00') 每天8点执行
}

提醒方式实现

A. 邮件提醒(使用PHPMailer或Laravel Mail)

function sendReminder($userId, $orderId) {
    $user = getUser($userId); // 获取用户邮箱
    $subject = "订单逾期提醒 - #{$orderId}";
    $body = "您的订单 #{$orderId} 已逾期,请尽快处理!";
    // 使用PHPMailer
    $mail = new PHPMailer\PHPMailer\PHPMailer();
    $mail->isSMTP();
    $mail->Host = 'smtp.example.com';
    $mail->SMTPAuth = true;
    $mail->Username = 'your@email.com';
    $mail->Password = 'password';
    $mail->setFrom('noreply@example.com', '系统');
    $mail->addAddress($user['email']);
    $mail->Subject = $subject;
    $mail->Body = $body;
    $mail->send();
}

B. 短信提醒(集成第三方API,如阿里云短信)

// 使用阿里云SDK
use AlibabaCloud\Client\AlibabaCloud;
AlibabaCloud::accessKeyClient('accessKeyId', 'accessKeySecret')
            ->regionId('cn-hangzhou')
            ->asDefaultClient();
$result = AlibabaCloud::rpc()
                      ->product('Dysmsapi')
                      ->version('2017-05-25')
                      ->action('SendSms')
                      ->method('POST')
                      ->options([
                          'query' => [
                              'PhoneNumbers' => $user['phone'],
                              'SignName' => '您的签名',
                              'TemplateCode' => 'SMS_123456',
                              'TemplateParam' => json_encode(['orderId' => $orderId]),
                          ],
                      ])
                      ->request();

C. 系统站内通知(存入通知表)

// 创建通知记录
$pdo->prepare("INSERT INTO notifications (user_id, type, data, read_at) 
               VALUES (?, 'overdue_remind', ?, NULL)")
    ->execute([$userId, json_encode(['order_id' => $orderId])]);

方案三:实时提醒(WebSocket + 事件驱动)

对于需要即时提醒的场景(如用户登录后立刻看到):

  1. 使用 Redis Pub/SubLaravel Echo + Pusher
  2. 在Cron脚本执行后,发布事件到消息队列
  3. 前端通过WebSocket监听事件,立即弹出提醒

防重复提醒策略

  • 字段控制:记录 last_remind_time,只对超过一定时间(如24小时)未提醒的记录发通知
  • 状态机:将状态变为 overdue 后不再重复提醒,除非状态重置
  • 幂等性:在发送前检查 remind_at 是否在最近N小时内

监控与日志

// 记录执行日志
file_put_contents('/var/log/overdue.log', 
    date('Y-m-d H:i:s') . " - Processed order #{$orderId}\n", 
    FILE_APPEND);

方法 适用场景 优点 缺点
Cron Job 标准PHP项目 稳定可靠,不依赖框架 需要服务器crontab权限
Laravel Scheduler Laravel项目 配置简单 仅限Laravel
WebSocket 需要即时通知 用户体验好 增加服务器复杂度
第三方服务 短信/邮件 无需自建基础设施 需要付费

推荐组合:Cron Job(定时检测) + 邮件/短信(通知)+ 数据库状态控制(防重复)。

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