-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtask.php
199 lines (165 loc) · 4.11 KB
/
task.php
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
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
<?php
/**
* PHP定时任务
* @author wuquanyao <git@yeahphp.com>
* @link http://www.yeahphp.com
*/
class Task
{
/**
* @var string 定时任务日志文件
*/
protected $log = "./task.log";
/**
* @var string 定时任务进程ID
*/
protected $pid = "./task.pid";
/**
* @var string 定时任务配置目录
*/
protected $cmd = "./cmd";
/**
* @var boolean 是否执行命令日志
*/
protected $printLog = true;
/**
* @var array
*/
protected $command = [];
/**
* 构造函数
*/
public function __construct()
{
$this->init();
}
/**
* 环境初始化
*/
protected function init()
{
if(PATH_SEPARATOR == ";") {
$this->warn("please run linux or mac system");
}
if(PHP_SAPI != "cli") {
$this->warn("please run php-cli mode");
}
if(!is_dir($this->cmd)) {
$this->warn("not found command dir: " . $this->cmd);
}
$this->command();
}
/**
* 解析命令
*/
protected function command()
{
$files = glob($this->cmd . "/*.php");
foreach ($files as $file) {
$cmds = include $file;
if(!is_array($cmds)) {
$this->warn("command return format:" . var_export([["second", "command"], "..."], true));
}
foreach ($cmds as $cmd) {
if(!is_array($cmd) || count($cmd) != 2) {
continue;
}
if(!isset($cmd[0]) || !is_numeric($cmd[0]) || $cmd[0] < 1) {
continue;
}
if(!isset($cmd[1]) || !is_string($cmd[1]) || trim($cmd[0]) == "") {
continue;
}
$this->command[] = [intval($cmd[0]), $cmd[1], 0];
}
}
}
/**
* 输出运行错误并退出
* @param string $msg
*/
protected function warn($msg)
{
exit("\033[41;33m {$msg} \033[0m \r\n");
}
/**
* 定时任务处理器
*/
protected function handler()
{
$time = time();
foreach($this->command as &$cmd) {
if($cmd[2] === 0 || ($time - $cmd[2] >= $cmd[0])) {
system($cmd[1]);
if(true === $this->printLog) {
file_put_contents(
$this->log,
"进程ID: " . getmypid() . ", 执行间隔:{$cmd[0]} 秒, 执行命令:{$cmd[1]}, 执行日期:" . date("Y-m-d H:i:s", $time) . "\r\n",
FILE_APPEND
);
}
$cmd[2] = $time;
}
}
}
/**
* 安装信号处理器
*/
protected function install()
{
pcntl_signal(SIGALRM, function() {
$this->handler();
pcntl_alarm(1);
});
}
/**
* 是否记录执行命令日志
* @param boolean $print
*/
public function printLog($print)
{
if(is_bool($print)) {
$this->printLog = $print;
}
}
/**
* 读取上一个进程PID
* @return int
*/
public function pid()
{
if(is_file($this->pid)) {
return file_get_contents($this->pid);
}
}
/**
* 杀死进程
* @return Task
*/
public function kill($pid = null)
{
$pid = $pid ? : trim($this->pid());
if(is_numeric($pid) && posix_kill($pid, SIGKILL)) {
echo "\033[41;30m 进程{$pid}退出成功 \033[0m \r\n";
}
return $this;
}
/**
* 运行定时任务
*/
public function run()
{
$pid = getmypid();
echo sprintf("\033[42;30m 任务进程%s运行 \033[0m \r\n", $pid);
//记录当前进程
file_put_contents($this->pid, $pid);
//安装信号处理器
self::install();
//向进程发送闹铃信号
pcntl_alarm(1);
while (true) {
pcntl_signal_dispatch();
sleep(1);
}
}
}