-
Notifications
You must be signed in to change notification settings - Fork 6
Expand file tree
/
Copy pathcron.php
More file actions
163 lines (134 loc) · 5.4 KB
/
cron.php
File metadata and controls
163 lines (134 loc) · 5.4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
<?php
/**
* @file cron.php
* @brief 定时任务脚本
*
* 该脚本用于在特定时间间隔内执行 update.php,以实现定时任务功能。
*
* 作者: Tak
* GitHub: https://github.com/taksssss/EPG-Server
* 二次开发: mxdabc
* Github: https://github.com/mxdabc/epgphp
*/
// 引入公共脚本,初始化数据库
require_once 'public.php';
initialDB();
// 取消时间限制
set_time_limit(0);
// 设置脚本只能通过CLI运行
if (php_sapi_name() !== 'cli') {
die("此脚本只能通过 CLI 运行");
}
// 日志记录函数
function logCronMessage($message) {
global $db;
try {
$timestamp = date('Y-m-d H:i:s'); // 使用设定的时区时间
$stmt = $db->prepare("INSERT INTO cron_log (timestamp, log_message) VALUES (:timestamp, :message)");
$stmt->bindValue(':timestamp', $timestamp, PDO::PARAM_STR);
$stmt->bindParam(':message', $message);
$stmt->execute();
} catch (PDOException $e) {
die("日志记录失败: " . $e->getMessage());
}
}
$currentPid = posix_getpid(); // 获取当前进程ID
$processName = 'cron.php';
$oldPids = [];
exec("pgrep -f '{$processName}'", $oldPids);
foreach ($oldPids as $pid) {
if ($pid != $currentPid && posix_kill($pid, 0)) {
if (posix_kill($pid, 9)) {
logCronMessage("【终止旧进程】 {$pid}");
} else {
logCronMessage("无法终止旧的进程 {$pid}");
}
}
}
// 从配置中获取间隔时间,如果不存在则默认为0
$interval_time = $Config['interval_time'] ?? 0;
// 如果间隔时间为0,则不执行
if ($interval_time == 0) {
logCronMessage("【取消定时任务】间隔时间设置为0。");
exit;
}
// 检查配置中是否存在首次执行时间和结束时间
if (!isset($Config['start_time']) || !isset($Config['end_time'])) {
logCronMessage("不存在首次执行时间或结束时间。退出...");
exit;
}
// 启动事务
$db->beginTransaction();
// 从配置中获取首次执行时间和结束时间
$start_time = $Config['start_time'];
$end_time = $Config['end_time'];
list($first_run_hour, $first_run_minute) = explode(':', $start_time);
list($end_hour, $end_minute) = explode(':', $end_time);
// 获取当前时间
$current_time = time();
// 计算今天的首次执行时间
$first_run_today = strtotime(date('Y-m-d') . " $first_run_hour:$first_run_minute:00");
// 计算明天的结束时间或今天的结束时间
if ($end_hour > $first_run_hour || ($end_hour == $first_run_hour && $end_minute > $first_run_minute)) {
// 结束时间在今天
$end_time_today = strtotime(date('Y-m-d') . " $end_hour:$end_minute:00");
} else {
// 结束时间在明天
$end_time_today = strtotime(date('Y-m-d', strtotime('+1 day')) . " $end_hour:$end_minute:00");
}
// 如果当前时间已经超过结束时间,则下次执行时间为明天的首次执行时间
if ($current_time >= $end_time_today) {
$next_execution_time = $first_run_today + 24 * 3600; // 加一天
} else {
// 计算从今天首次执行时间开始的下一个执行时间
$next_execution_time = $first_run_today + ceil(($current_time - $first_run_today) / $interval_time) * $interval_time;
}
// 如果跨越了结束时间,则设置为明天的首次执行时间
if ($next_execution_time >= $end_time_today) {
$first_run_today += 24 * 3600; // 更新明天的开始时间
$end_time_today += 24 * 3600; // 更新明天的结束时间
$next_execution_time = $first_run_today; // 重置为明天首次执行时间
}
// 计算距离下一个执行时间的秒数
$initial_sleep = $next_execution_time - $current_time;
// 汇总所有日志信息
logCronMessage("【开始时间】 " . date('H:i', $first_run_today));
logCronMessage("【结束时间】 " . date('H:i', $end_time_today));
$logContent = "【间隔时间】 " . gmdate('H小时i分钟', $interval_time) . "\n";
$logContent .= "\t\t\t\t-------运行时间表-------\n";
// 循环输出每次执行的时间
$current_execution_time = $first_run_today;
while ($current_execution_time < $end_time_today) {
$logContent .= "\t\t\t\t\t " . date('H:i', $current_execution_time) . "\n";
$current_execution_time += $interval_time;
}
$logContent .= "\t\t\t\t--------------------------";
logCronMessage($logContent);
logCronMessage("【下次执行】 " . date('m/d H:i', $next_execution_time));
logCronMessage("【等待时间】 " . gmdate('H小时i分钟', $initial_sleep));
// 提交事务
$db->commit();
// 首先等待到下一个执行时间
sleep($initial_sleep);
// 无限循环,可以使用实际需求中的退出条件
while (true) {
// 执行update.php
exec('php ' . __DIR__ . '/update.php');
logCronMessage("【成功执行】 update.php");
// 计算下一个执行时间
$current_time = time();
$next_execution_time += $interval_time;
// 如果跨越了结束时间,则设置为明天的首次执行时间
if ($next_execution_time >= $end_time_today) {
$first_run_today += 24 * 3600; // 更新明天的开始时间
$end_time_today += 24 * 3600; // 更新明天的结束时间
$next_execution_time = $first_run_today; // 重置为明天首次执行时间
}
// 计算等待时间
$sleep_time = $next_execution_time - $current_time;
// 记录下次执行时间
logCronMessage("【下次执行】 " . date('m/d H:i', $next_execution_time));
// 等待到下一个执行时间
sleep($sleep_time);
}
?>