PHP实现javascript的定时器

392 阅读1分钟

主要思路还是通过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上下载

github.com/fireqong/ti…