php毫秒定时器,基于event扩展

dazhaozhao

由于evnet扩展,在windows上也可以安装,所以此定时器也可以在win上进行演示,生产环境还是要基于workerman,在linux实现。
为了学习workerman,又抄了一个event出来, 毫秒定时器,workerman就是检测php环境上是否有php扩展,如果有就优先,然后才是Select类。

<?php
class Timer
{

    const EV_TIMER = 1;

    const EV_TIMER_ONCE = 2;

    /**
     * Event base.
     * @var object
     */
    protected $_eventBase = null;

    /**
     * All listeners for read/write event.
     * @var array
     */
    protected $_allEvents = array();

    /**
     * Event listeners of signal.
     * @var array
     */
    protected $_eventSignal = array();

    /**
     * All timer event listeners.
     * 
     * @var array
     */
    protected $_eventTimer = array();

    /**
     * Timer id.
     * @var int
     */
    protected static $_timerId = 1;

    /**
     * construct
     * @return void
     */

    public function __construct()
    {

        if (class_exists('\\\\EventBase', false)) {
            $class_name = '\\\\EventBase';
        } else {
            $class_name = '\EventBase';
        }
        $this->_eventBase = new $class_name();
    }

    /**
     * @see EventInterface::add()
     */
    public function add($fd, $flag, $func, $args = array())
    {
        if (class_exists('\\\\Event', false)) {
            $class_name = '\\\\Event';
        } else {
            $class_name = '\Event';
        }

        $param = array($func, (array) $args, $flag, $fd, self::$_timerId);
        $event = new $class_name($this->_eventBase, -1, $class_name::TIMEOUT | $class_name::PERSIST, array($this, "timerCallback"), $param);
        if (!$event || !$event->addTimer($fd)) {
            return false;
        }
        $this->_eventTimer = $event;
        return self::$_timerId++;
    }

    /**
     * @see Events\EventInterface::del()
     */
    public function del($fd, $flag)
    {
        if (isset($this->_eventTimer)) {
            $this->_eventTimer->del();
            unset($this->_eventTimer);
        }
        return true;
    }

    /**
     * Timer callback.
     * @param null $fd
     * @param int $what
     * @param int $timer_id
     */
    public function timerCallback($fd, $what, $param)
    {
        $timer_id = $param;

        if ($param === self::EV_TIMER_ONCE) {
            $this->_eventTimer->del();
            unset($this->_eventTimer);
        }

        try {
            call_user_func_array($param, $param);
        } catch (\Exception $e) {
            exit(250);
        } catch (\Error $e) {
            exit(250);
        }
    }

    /**
     * @see Events\EventInterface::clearAllTimer()
     * @return void
     */
    public function clearAllTimer()
    {
        foreach ($this->_eventTimer as $event) {
            $event->del();
        }
        $this->_eventTimer = array();
    }

    /**
     * @see EventInterface::loop()
     */
    public function loop()
    {
        $this->_eventBase->loop();
    }

    /**
     * Destroy loop.
     *
     * @return void
     */
    public function destroy()
    {
        foreach ($this->_eventSignal as $event) {
            $event->del();
        }
    }

    /**
     * Get timer count.
     *
     * @return integer
     */
    public function getTimerCount()
    {
        return count($this->_eventTimer);
    }
}

function microtime_float()
{
    list($usec, $sec) = explode(" ", microtime());
    return bcadd($usec, $sec, 3);
}

$timer = new Timer();

$timer->add(0.5, Timer::EV_TIMER, function () {
    echo microtime_float() . "\n";
});

$timer->add(1, Timer::EV_TIMER_ONCE, function () {
    echo microtime_float() . "once \n";
});

//待删除的id
$id = $timer->add(5, Timer::EV_TIMER, function () {
    echo "clean up after running once\n";
});

//删除定时器
$timer->add(6, Timer::EV_TIMER_ONCE, function () use ($id, $timer) {
    $timer->del($id, Timer::EV_TIMER);
});

$timer->loop();
3346 1 1
1个回答

six

强悍,可以拿出来放到自己小项目中用了

  • 暂无评论
年代过于久远,无法发表回答
🔝