PHP项目如何实现合同到期提醒?

wen java案例 1

本文目录导读:

PHP项目如何实现合同到期提醒?

  1. 方案一:用户访问时触发提醒(被动模式)
  2. 方案二:定时任务主动推送(推荐)
  3. 方案三:集成到框架中的最佳实践
  4. 注意事项

实现PHP合同到期提醒,通常有两种模式:被动检查(用户访问时触发)和主动推送(服务器定时执行),以下是具体的实现方案和代码示例。

用户访问时触发提醒(被动模式)

适合后台管理系统,用户登录或刷新页面时检查合同。

数据库表设计

CREATE TABLE contracts (
    id INT AUTO_INCREMENT,
    contract_name VARCHAR(255),
    end_date DATE,
    remind_days INT DEFAULT 30,  -- 提前多少天提醒
    status TINYINT DEFAULT 1,    -- 1:生效 0:已结束
    PRIMARY KEY (id)
);

PHP 查询即将到期合同

<?php
// 连接数据库(使用PDO)
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
// 计算提醒日期范围:到 提醒天数
$today = date('Y-m-d');
$sql = "SELECT * FROM contracts 
        WHERE status = 1 
        AND end_date BETWEEN :today AND :remind_date 
        ORDER BY end_date ASC";
$stmt = $pdo->prepare($sql);
$stmt->execute([
    ':today' => $today,
    ':remind_date' => date('Y-m-d', strtotime('+30 days')) // 提前30天
]);
$reminders = $stmt->fetchAll(PDO::FETCH_ASSOC);
// 输出提醒
foreach ($reminders as $contract) {
    echo "合同【{$contract['contract_name']}】将于 {$contract['end_date']} 到期!\n";
}
?>

在后台页面嵌入提醒逻辑

可以在后台框架的 BaseController 或公共模板中执行上述查询,并在页面顶部显示倒计时或弹窗。

定时任务主动推送(推荐)

适合需要邮件、短信或钉钉/企业微信通知,无需用户登录即可触发。

编写 PHP 脚本 remind.php

<?php
// 加载数据库连接和配置
$pdo = new PDO('mysql:host=localhost;dbname=test', 'root', '');
// 获取所有即将到期(且未发送提醒)的合同
$sql = "SELECT * FROM contracts 
        WHERE status = 1 
        AND remind_sent = 0 
        AND end_date BETWEEN CURDATE() AND DATE_ADD(CURDATE(), INTERVAL remind_days DAY)";
$contracts = $pdo->query($sql)->fetchAll();
foreach ($contracts as $contract) {
    // 1. 发送邮件(示例使用 mail(),实际建议 PHPMailer)
    $subject = "合同到期提醒:{$contract['contract_name']}";
    $message = "合同《{$contract['contract_name']}》将于 {$contract['end_date']} 到期,请及时处理。";
    mail('admin@example.com', $subject, $message);
    // 2. 发送短信/钉钉机器人(可接入第三方API)
    // 例如使用发短信API:sms_send('13800138000', $message);
    // 3. 标记已发送,避免重复提醒
    $update = $pdo->prepare("UPDATE contracts SET remind_sent = 1 WHERE id = ?");
    $update->execute([$contract['id']]);
}

设置 Linux 定时任务(Crontab)

# 每天早8点执行一次
0 8 * * * /usr/bin/php /path/to/remind.php >> /var/log/contract_remind.log 2>&1

扩展:支持多频次提醒

可以在数据库增加 remind_stages 字段(如:30天、7天、1天各提醒一次),每次执行时检查时间差。

集成到框架中的最佳实践

以 Laravel 为例(其他框架思路类似):

创建 Artisan 命令

php artisan make:command ContractReminder

实现 handle() 方法:

public function handle()
{
    $contracts = Contract::where('status', 1)
        ->where('end_date', '<=', now()->addDays(30))
        ->where('end_date', '>=', now())
        ->get();
    foreach ($contracts as $contract) {
        // 发送通知(Laravel Notifications)
        $contract->owner->notify(new ContractExpiring($contract));
    }
}

配置任务调度

App\Console\Kernel.php 中添加:

protected function schedule(Schedule $schedule)
{
    $schedule->command('contract:remind')->dailyAt('09:00');
}

然后执行 php artisan schedule:run 或设置服务器Crontab:

* * * * * cd /your-project && php artisan schedule:run >> /dev/null 2>&1

注意事项

问题 解决方案
时区不一致 数据库和PHP代码统一使用 Asia/Shanghai 时区
重复提醒 使用 remind_sent 字段或检查上次提醒时间戳
大量合同性能 使用索引(end_date, status),分页查询
通知失败 记录日志并在失败时重试(或使用消息队列)
用户自定义提醒 在合同表增加 remind_days 字段,允许用户设置
  • 简单管理后台:用方案一,在页面加载时查询即将到期合同并展示。
  • 自动化通知:用方案二(定时脚本)或方案三(框架调度),结合邮件/短信/微信通知。
  • 进阶需求:可使用 Redis 存储提醒状态,或使用消息队列(如 RabbitMQ)异步发送通知。

最终选择取决于你的项目规模、运维能力和通知渠道要求,如果是企业级应用,建议使用方案三(框架+定时任务)并增加失败重试和日志监控。

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