我想在PHP中使用定时器,在一定的时间段(没有玩家活动)后发送邮件?这是通过套接字进行多人游戏的。PHP和定时器事件
我用Google搜索和stackoverflew,发现如下
- 可以使用一个cron(需要 synronize我的PHP类(基于socket )和cron ...),不,我 猜测。
- 可以使用睡眠...如果它可以等待 不到一秒钟,我将有 给出一个尝试,没有再次,我想
- 可以使用register_tick_function ... 不适用我觉得
有没有想法? 谢谢!
我想在PHP中使用定时器,在一定的时间段(没有玩家活动)后发送邮件?这是通过套接字进行多人游戏的。PHP和定时器事件
我用Google搜索和stackoverflew,发现如下
有没有想法? 谢谢!
这里有几个概念是如何做到这一点: 1.常见的概念是用于发送消息的创建脚本,然后将其添加到服务器的Cron申请,并指定时间执行脚本。 2.编写Python脚本,将控制你的PHP应用程序文件或部分,在Python的条款,您可以派生于服务器启动过程中,会做你的任务,每一个时间量(以无限循环我猜...同时1:..) 3.编写shell .sh文件,该文件将调用php或python脚本,并将此脚本的控件添加到/etc/init.d以使其更加可控。
这是我写来处理我的时间需求。它不会奇迹般地中断你的代码,但它提供了一个非常灵活的方式来安排定时器。你所要做的就是确保你每隔一段时间运行$ events-> CheckTimers()。
的libevent的模块可以做更多,但是这一点更多的努力。
$events = new Events();
function callback($text) {
printf("I'm a timer callback %s\n", $text);
}
$events->AddTimer("5s", "callback", "every 5 seconds", EVENTS::EVENT_REPEAT);
$events->AddTimer("2s..15s", "callback", "random time 2 to 15 seconds", EVENTS::EVENT_REPEAT);
$events->AddTimer("1m", create_function('', "echo 'Im a LAMBDA function that runs every minute\n';"), false, EVENTS::EVENT_REPEAT);
$events->AddTimer("1h..2h", "callback", "I will run once, in between 1 and 2 hours");
# This is just an example, in reality, you would make sure to call CheckTimer() regulary (ideally not more than once a second)
while (true) {
$events->CheckTimers();
printf("Next timer in %s seconds...\n", $ne = $events->GetNextTimer(), gettype($ne));
sleep(1);
}
class Events {
const EVENT_REPEAT = 0x0001;
const EVENT_SEQUENCE = 0x0002;
var $events;
var $timers;
function __construct() {
$this->events = array();
$this->timers = array();
}
function AddTimer($when, $action, $args = false, $flags = 0) {
if (preg_match('#([0-9a-zA-Z]+)..([0-9a-zA-Z]+)#', $when, $a)) {
$time = time(NULL) + rand($this->time2seconds($a[1]), $this->time2seconds($a[2]));
} else {
$time = time(NULL) + $this->time2seconds($when);
}
if ($flags & self::EVENT_SEQUENCE) {
while ($this->IsArrayCount($this->timers[$time])) {
$time ++;
}
}
$this->timers[$time][] = array("when" => $when, "action" => $action, "args" => $args, "flags" => $flags);
ksort($this->timers);
}
function GetNextTimer() {
if (!$this->IsArrayCount($this->timers)) {
return false;
}
reset($this->timers);
$firstevent = each($this->timers);
if ($firstevent === false) {
return false;
}
$time = $firstevent["key"];
$nextEvent = $time - time(NULL);
if ($nextEvent < 1) {
return 1;
}
return $nextEvent;
}
function CheckTimers() {
$rv = false;
$now = time(NULL);
foreach ($this->timers as $time => $events) {
if ($time > $now) {
break;
}
foreach ($events as $key => $event) {
# debug("Event::CheckTimer: {$event["action"]}");
# ircPubMsg("Event::CheckTimer: {$event["action"]}", "#bots");
if (!$event["args"]) {
call_user_func($event["action"]);
} else {
$rv = call_user_func_array($event["action"], is_array($event["args"]) ? $event["args"] : array($event["args"]));
}
unset($this->timers[$time][$key]);
if ($event["flags"] & self::EVENT_REPEAT) {
$this->AddTimer($event["when"], $event["action"], $event["args"], $event["flags"]);
}
if ($rv) {
# break;
}
}
if (!$this->IsArrayCount($this->timers[$time])) {
unset($this->timers[$time]);
}
if (0 && $rv) {
break;
}
}
if ($rv) {
return $rv;
}
}
function time2seconds($timeString) {
$end = substr($timeString, strlen($timeString) - 1);
$seconds = intval($timeString); // = preg_replace("#[^0-9]#", "", $a);
if (is_numeric($end)) {
return $seconds;
}
$unim = array("s","m","h","d", "w", "m", "y");
$divs = array(1, 60, 60, 24, 7, 28, 12, false);
$found = false;
while (!$found) {
$u = array_shift($unim);
$d = array_shift($divs);
$seconds *= $d;
if ($end === $u) {
return $seconds;
}
}
return intval($timeString);
}
function IsArrayCount($possibleArray) {
return (isset($possibleArray) && is_array($possibleArray)) ? count($possibleArray) : false;
}
}
如果睡眠的粒度太大,那么总是有[usleep](http://www.php.net/usleep)函数。无论如何,很难推荐一种没有更多信息的方法。 (例如,是否始终连接来自客户端的套接字连接。) – 2011-02-17 15:51:50
来自客户端的连接是始终连接的。 – tit 2011-02-17 15:55:53