|
定时器,在 WEB 应用中比较常见,比如:每天凌晨2点自动备份数据库,这个功能就要使用定时器。现在使用的定时器方案大多数都是 Linux 的 Crontab 命令(或者是 Window 中的任务计划),写一个 shell 脚本,在脚本中执行操作。其实 PHP 也是完全可以实现定时器功能的,这里需要使用 PCNTL 模块,此模块默认是没有安装的,如果没有安装只需要在编译 PHP 的时候,添加 --enable-pcntl 配置选项重新编译 PHP 即可。
直接上代码,代码都是说明注释。如果不能,请留言:
[pre]
<?php
class Timer
{
private $seconds = 1; // 秒数,每隔多少秒会执行一次
private $callback = ""; // 功能函数,即您要实现的功能
private $isdaemon = false; // 是否开启守护进程
// 构造函数,
// 第一个是 秒数(正整数)
// 第二个参数是一个 bool,是否开启守护进程
// 第三个参数为要实现的功能
public function __construct(int $seconds, $isdaemon = false, $callback = "")
{
if($seconds >= 0) $this->seconds = $seconds;
$this->isdaemon = (bool)$isdaemon;
// 保存第三个参数是一个匿名函数
if($callback instanceof Closure)
{
$this->callback = $callback;
} else {
$this->callback = function() {};
}
}
// 程序运行
public function start()
{
if($this->isdaemon)
$this->start_daemon();
// 安装一个信号处理器
pcntl_signal(SIGALRM, array($this, 'installHandler'));
// 启用异步信号处理
pcntl_async_signals(true);
// 设置闹钟信号
pcntl_alarm($this->seconds);
// 进入死循环,防止程序终止
while(true);
}
// 信号处理函数
public function installHandler()
{
// 调用客户需要操作的函数
call_user_func($this->callback);
// 重新设置闹钟
pcntl_alarm($this->seconds);
}
// 开启守护进程
public function start_daemon()
{
if(($pid = pcntl_fork()) < 0) {
exit("start daemon error()");
} else if($pid) { // 如果是父进程,则终止程序
exit();
} else {
}
}
}
// 客户端调用,每隔 1 秒打印一下当前的时间
// 第 1 个参数,表示每隔 1 秒执行一次
// 第 2 个参数,表示 不开启 守护进程
// 第 3 个参数,表示要做的功能
$timer = new Timer(1, false, function()
{
echo date("Y-m-d H:i:s\n");
});
$timer->start();
?>
[/pre]
当然,我们也可以采用 swoole 这种扩展,如果用 swoole 的话,那是很简单的,一句话,就可以搞定。如:
[pre]
swoole_timer_tick(1000, function()
{
echo date("Y-m-d H:i:s\n");
});
[/pre]
不管是直接用 PHP 来写,还是 swoole 来写,最都可以实现我们想要的功能。但是,在实际项目中,最好不要用 PHP 来实现定时器,还是利用 Linux 的 Crontab 效率更高些,也更方便些。 |
|