主要思路还是通过libevent来实现, PHP的Event扩展实现了PHP与libevent库的对接,所以我们只需要安装Event扩展就可以使用libevent的功能。
废话不多说,上代码:
<?php
namespace Church;
use Event;
use EventBase;
class Reactor
{
protected $eventBase;
protected $events;
public function __construct()
{
$this->eventBase = new EventBase();
}
public function addTimer($second, $what, $cb, $arg = null)
{
$event = new Event($this->eventBase, -1, $what, $cb, $arg);
$event->add($second);
$this->events[spl_object_hash($event)] = $event;
return $event;
}
public function del($resource)
{
$event = $this->events[spl_object_hash($resource)];
$event->del();
$event->free();
}
public function start()
{
$this->eventBase->loop();
}
}
<?php
namespace Church;
use Event;
class Timer
{
protected static $reactor = null;
public static function setTimeout($callback, $millisecond)
{
self::checkTimeFormat($millisecond);
$reactor = self::getReactor();
return $reactor->addTimer($millisecond / 1000, Event::TIMEOUT, $callback);
}
public static function setInterval($callback, $millisecond)
{
self::checkTimeFormat($millisecond);
$reactor = self::getReactor();
return $reactor->addTimer($millisecond / 1000, Event::TIMEOUT | Event::PERSIST, $callback);
}
public static function clearTimeout($event)
{
self::clear($event);
}
public static function clearInterval($event)
{
self::clear($event);
}
public static function clear($event)
{
$reactor = self::getReactor();
$reactor->del($event);
}
public static function loop()
{
self::getReactor()->start();
}
public static function checkTimeFormat($millisecond)
{
if ($millisecond < 1) {
trigger_error('Millisecond can not less than 1');
}
}
protected static function getReactor()
{
if (is_null(self::$reactor)) {
self::$reactor = new Reactor();
}
return self::$reactor;
}
}
代码非常简单,就是内置类的使用,有些使用技巧相信朋友们很容易可以看出来,我也不作过多的解释。
使用:
<?php
use Church\Timer;
Timer::setInterval(function() {
//do something
echo "hello!world", PHP_EOL;
}, 100);
Timer::loop();
全部代码可以在github上下载