2011-02-17 22 views
1

我想在PHP中使用定时器,在一定的时间段(没有玩家活动)后发送邮件?这是通过套接字进行多人游戏的。PHP和定时器事件

我用Google搜索和stackoverflew,发现如下

  • 可以使用一个cron(需要 synronize我的PHP类(基于socket )和cron ...),不,我 猜测。
  • 可以使用睡眠...如果它可以等待 不到一秒钟,我将有 给出一个尝试,没有再次,我想
  • 可以使用register_tick_function ... 不适用我觉得

有没有想法? 谢谢!

+0

如果睡眠的粒度太大,那么总是有[usleep](http://www.php.net/usleep)函数。无论如何,很难推荐一种没有更多信息的方法。 (例如,是否始终连接来自客户端的套接字连接。) – 2011-02-17 15:51:50

+0

来自客户端的连接是始终连接的。 – tit 2011-02-17 15:55:53

回答

0

PHP是否对你的工作time_nanosleep()?或usleep()

+0

两者之间的实际区别是什么? – 2011-02-17 15:56:08

0

这里有几个概念是如何做到这一点: 1.常见的概念是用于发送消息的创建脚本,然后将其添加到服务器的Cron申请,并指定时间执行脚本。 2.编写Python脚本,将控制你的PHP应用程序文件或部分,在Python的条款,您可以派生于服务器启动过程中,会做你的任务,每一个时间量(以无限循环我猜...同时1:..) 3.编写shell .sh文件,该文件将调用php或python脚本,并将此脚本的控件添加到/etc/init.d以使其更加可控。

4

这是我写来处理我的时间需求。它不会奇迹般地中断你的代码,但它提供了一个非常灵活的方式来安排定时器。你所要做的就是确保你每隔一段时间运行$ 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; 
    } 
}