add

int \Workerman\Timer::add(float $time_interval, callable $callback [,$args = array(), bool $persistent = true])

Execute a function or class method at specified intervals.

Note: The timer runs in the current process; Workerman does not create new processes or threads to run the timer.

Parameters

time_interval

The interval at which to execute, in seconds, supporting decimals and can be precise to 0.001, which is accurate to millisecond level.

callback

The callback function. Note: If the callback function is a class method, then the method must be public.

args

The parameters for the callback function, which must be an array containing parameter values.

persistent

Indicates whether it is persistent. If you only want to execute it once, pass false (tasks that are run once are automatically destroyed after execution, no need to call Timer::del() afterward). The default is true, meaning it will continue to run at intervals.

Return Value

Returns an integer representing the timer's timerid, which can be destroyed by calling Timer::del($timerid).

Example

1. Timer function as an anonymous function (closure)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$task = new Worker();
// The number of processes to run the timer task, be cautious of concurrency issues in multi-process business logic
$task->count = 1;
$task->onWorkerStart = function(Worker $task)
{
    // Executes every 2.5 seconds
    $time_interval = 2.5;
    Timer::add($time_interval, function()
    {
        echo "task run\n";
    });
};

// Run worker
Worker::runAll();

2. Set timer only in a specific process

A worker instance has 4 processes, set the timer only in the process with ID number 0.

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$worker = new Worker();
$worker->count = 4;
$worker->onWorkerStart = function(Worker $worker)
{
    // Set timer only in the process with ID number 0; no timers are set in processes 1, 2, and 3.
    if($worker->id === 0)
    {
        Timer::add(1, function(){
            echo "4 worker processes, timer set only in process 0\n";
        });
    }
};
// Run worker
Worker::runAll();

3. Timer function as an anonymous function, passing parameters using a closure

use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 8;
// Set timer for the corresponding connection when it is established
$ws_worker->onConnect = function(TcpConnection $connection)
{
    // Executes every 10 seconds
    $time_interval = 10;
    $connect_time = time();
    // Temporarily add a timer_id property to the connection object to store the timer id
    $connection->timer_id = Timer::add($time_interval, function() use ($connection, $connect_time)
    {
         $connection->send($connect_time);
    });
};
// When the connection closes, delete the corresponding timer
$ws_worker->onClose = function(TcpConnection $connection)
{
    // Delete the timer
    Timer::del($connection->timer_id);
};

// Run worker
Worker::runAll();

4. Timer function as an anonymous function, passing parameters through the timer interface

use Workerman\Worker;
use Workerman\Timer;
use Workerman\Connection\TcpConnection;
require_once __DIR__ . '/vendor/autoload.php';

$ws_worker = new Worker('websocket://0.0.0.0:8080');
$ws_worker->count = 8;
// Set timer for the corresponding connection when it is established
$ws_worker->onConnect = function(TcpConnection $connection)
{
    // Executes every 10 seconds
    $time_interval = 10;
    $connect_time = time();
    // Temporarily add a timer_id property to the connection object to store the timer id
    $connection->timer_id = Timer::add($time_interval, function($connection, $connect_time)
    {
         $connection->send($connect_time);
    }, array($connection, $connect_time));
};
// When the connection closes, delete the corresponding timer
$ws_worker->onClose = function(TcpConnection $connection)
{
    // Delete the timer
    Timer::del($connection->timer_id);
};

// Run worker
Worker::runAll();

5. Timer function as a regular function

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

// Regular function
function send_mail($to, $content)
{
    echo "send mail ...\n";
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    // Executes the send mail task after 10 seconds, passing false as the last parameter indicates it runs only once
    Timer::add(10, 'send_mail', array($to, $content), false);
};

// Run worker
Worker::runAll();

6. Timer function as a class method

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Note that the callback function must be public
    public function send($to, $content)
    {
        echo "send mail ...\n";
    }
}

$task = new Worker();
$task->onWorkerStart = function($task)
{
    // Sends an email after 10 seconds
    $mail = new Mail();
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    Timer::add(10, array($mail, 'send'), array($to, $content), false);
};

// Run worker
Worker::runAll();

7. Timer function as a class method (using timer internally)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Note that the callback function must be public
    public function send($to, $content)
    {
        echo "send mail ...\n";
    }

    public function sendLater($to, $content)
    {
        // If the callback method belongs to the current class, the first element of the callback array is $this
        Timer::add(10, array($this, 'send'), array($to, $content), false);
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Sends an email after 10 seconds
    $mail = new Mail();
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    $mail->sendLater($to, $content);
};

// Run worker
Worker::runAll();

8. Timer function as a static method of a class

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Note this is a static method, the callback function must also be public
    public static function send($to, $content)
    {
        echo "send mail ...\n";
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Sends an email after 10 seconds
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    // Timed call to the static method of the class
    Timer::add(10, array('Mail', 'send'), array($to, $content), false);
};

// Run worker
Worker::runAll();

9. Timer function as a static method of a class (with namespace)

namespace Task;

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    // Note this is a static method, the callback function must also be public
    public static function send($to, $content)
    {
        echo "send mail ...\n";
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Sends an email after 10 seconds
    $to = 'workerman@workerman.net';
    $content = 'hello workerman';
    // Timed call to the static method of the namespaced class
    Timer::add(10, array('\Task\Mail', 'send'), array($to, $content), false);
};

// Run worker
Worker::runAll();

10. Destroy the current timer inside the timer (using closure to pass $timer_id)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    // Count
    $count = 1;
    // To pass $timer_id correctly to the callback function, the address operator & must precede $timer_id
    $timer_id = Timer::add(1, function() use (&$timer_id, &$count)
    {
        echo "Timer run $count\n";
        // Destroy the current timer after running 10 times
        if($count++ >= 10)
        {
            echo "Timer::del($timer_id)\n";
            Timer::del($timer_id);
        }
    });
};

// Run worker
Worker::runAll();

11. Destroy the current timer inside the timer (pass $timer_id as a parameter)

use Workerman\Worker;
use Workerman\Timer;
require_once __DIR__ . '/vendor/autoload.php';

class Mail
{
    public function send($to, $content, $timer_id)
    {
        // Temporarily add a count property to the current object to record the number of timer runs
        $this->count = empty($this->count) ? 1 : $this->count;
        // Destroy the current timer after running 10 times
        echo "send mail {$this->count}...\n";
        if($this->count++ >= 10)
        {
            echo "Timer::del($timer_id)\n";
            Timer::del($timer_id);
        }
    }
}

$task = new Worker();
$task->onWorkerStart = function(Worker $task)
{
    $mail = new Mail();
    // To pass $timer_id correctly to the callback function, the address operator & must precede $timer_id
    $timer_id = Timer::add(1, array($mail, 'send'), array('to', 'content', &$timer_id));
};

// Run worker
Worker::runAll();