本文目录导读:

实现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)异步发送通知。
最终选择取决于你的项目规模、运维能力和通知渠道要求,如果是企业级应用,建议使用方案三(框架+定时任务)并增加失败重试和日志监控。
版权声明:足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播
足球直播
足球直播
足球直播
足球直播
足球直播
中超直播
中超直播
中超直播
中超直播
中超直播
英超直播
英超直播
英超直播
英超直播
英超直播
德甲直播
德甲直播
德甲直播
德甲直播
德甲直播
西甲直播
西甲直播
西甲直播
西甲直播
西甲直播
意甲直播
意甲直播
意甲直播
意甲直播
意甲直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
篮球直播
篮球直播
篮球直播
篮球直播
篮球直播