PHP Classes

File: Timers.class.php

Recommend this page to a friend!
  Classes of Sam S   setTimeout and setInterval   Timers.class.php   Download  
File: Timers.class.php
Role: Class source
Content type: text/plain
Description: The class and function definition file
Class: setTimeout and setInterval
Call a function after a period of time
Author: By
Last change: documentation fix
Date: 15 years ago
Size: 9,359 bytes
 

Contents

Class file image Download
<?php
/**
 * ************************ NOTICE ***********************************
 *
 * The use of Timers WILL slow down your script execution time.
 * By how much is determined by the user implementation.
 *
 * *******************************************************************
 *
 * This pacakge contains one class for handling timers in PHP
 * and enables the handling of callback functions at given intervals
 * in microseconds (NOT milliseconds like javascript), as well as
 * removing said functions from the stack of callable functions.
 *
 * The class is dependent on the PHP language construct declare(ticks=N);
 * where N represents how many "tickable statements" that get processed
 * before a registered tick function is called and MUST be declared in the top level script,
 * not an included file in order to be effective.
 *
 * @see http://us.php.net/manual/en/control-structures.declare.php#control-structures.declare.ticks
 *
 * The value of N determines
 * 1) how close to perfect accuracy the timers are (probably never be perfect though)
 * 2) how fast the script will be processed
 * If N == 1 the script will be very close to perfectly accurate, but will run very slow
 * but if N is set TOO high (like 10000) it may not be very effective or accurate.
 * It is up to the user to determine what this number should be for their script.
 *
 * The package also includes 4 functions for simplifying calls to the static methods of the class:
 * -- setTimeout, setInterval, clearTimeout, clearInterval
 *
 * @author Sam Shull <sam.shull@jhspecialty.com>
 * @version 0.5
 *
 * 07/19/2009
 * @copyright Copyright (c) 2009 Sam Shull <sam.shull@jhspeicalty.com>
 * @license <http://www.opensource.org/licenses/mit-license.html>
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
 *
 *
 * <code>
 * require_once 'Timers.class.php';
 *
 * $timer = setTimeout('print "\ntimeout";', 1000);
 *
 * //this is the part that makes the timers work,
 * ///but also slows the script down
 * declare(ticks=1);
 *
 * //do something else
 * </code>
 *
 * Changes -
 * 07/20/2009 - added Timers::microtime
 */

/**
 * Just for simplifying the Timers::setTimeout method
 *
 *
 * @param callable | string $func
 * @param integer $microseconds - remember this is microseconds NOT milliseconds
 *
 * @return integer
 */
function setTimeout ($func, $microseconds)
{
    return
Timers::setTimeout($func, $microseconds);
}

/**
 * Just for simplifying the Timers::setInterval method
 *
 *
 * @param callable | string $func
 * @param integer $microseconds - remember this is microseconds NOT milliseconds
 *
 * @return integer
 */
function setInterval ($func, $microseconds)
{
    return
Timers::setInterval($func, $microseconds);
}

/**
 * Just for simplifying the Timers::clearTimeout method
 *
 *
 * @param integer $interval - an integer representing the one returned from a call to setTimeout()
 *
 * @return boolean
 */
function clearTimeout ($func, $microseconds)
{
    return
Timers::setTimeout($func, $microseconds);
}

/**
 * Just for simplifying the Timers::clearInterval method
 *
 *
 * @param integer $interval - an integer representing the one returned from a call to setInterval()
 *
 * @return boolean
 */
function clearInterval ($interval)
{
    return
Timers::clearInterval($interval);
}

/**
 * This class contains a series of static properties and functions
 * that enable the creation and execution of timers
 *
 * @author Sam Shull
 */
class Timers
{
   
/**
     * An array of the arrays that represent
     * the timer information used by Timers::tick
     *
     * @access private
     * @staticvar array
     */
   
private static $timers = array();
   
   
/**
     * Tracker of timers
     *
     *
     * @access private
     * @staticvar integer
     */
   
private static $numTimers = 0;
   
   
/**
     * An array of the arrays that represent
     * the interval information used by Timers::tick
     *
     * @access private
     * @staticvar array
     */
   
private static $intervals = array();
   
   
/**
     * Tracker of intervals
     *
     *
     * @access private
     * @staticvar integer
     */
   
private static $numIntervals = 0;
   
   
/**
     * Used for debugging
     *
     *
     * @access private
     * @staticvar integer
     */
    //private static $ticks = 0;
   
    /**
     * A utility method called after N number of ticks by the engine
     * that checks each timer and interval to see if the desired
     * number of microseconds have passed and executes the function
     * when appropriate
     *
     * @static
     * @return void
     */
   
public static function tick ()
    {
       
//++self::$ticks;
       
       
$time = self::microtime();
       
        foreach (
self::$timers as $position => $timer)
        {
            if (
$time >= $timer['time'])
            {
               
call_user_func($timer['function']);
                unset(
self::$timers[$position]);
            }
        }
       
        foreach (
self::$intervals as $position => $timer)
        {
            if (
$time >= $timer['time'])
            {
               
call_user_func($timer['function']);
               
self::$intervals[$position]['time'] = self::microtime() + self::$intervals[$position]['microseconds'];
            }
        }
    }
   
   
/**
     * A utility method for retrieving the most accurate
     * microtime available
     *
     * @static
     * @return float
     */
   
public static function microtime ()
    {
        list(
$m, $s) = explode(' ', microtime());
        return
round(((float)$m + (float)$s) * 1000000);
    }
   
   
/**
     * A utility method that ensures that all the timeouts have been called
     * and that calls all the intervals one more time
     *
     *
     * @static
     * @return void
     */
   
public static function shutdown ()
    {
        foreach (
self::$timers as $position => $timer)
        {
           
call_user_func($timer['function']);
            unset(
self::$timers[$position]);
        }
       
        foreach (
self::$intervals as $position => $interval)
        {
           
call_user_func($interval['function']);
            unset(
self::$intervals[$position]);
        }
       
       
//print "\nticks: " . self::$ticks;
   
}
   
   
/**
     * Add a function to the be executed after ($microseconds) microsecond
     *
     * @static
     *
     * @param callable | string $func
     * @param integer $microseconds - remember microseconds, not miliseconds
     *
     * @return integer
     */
   
public static function setTimeout ($func, $microseconds)
    {
        if (!
is_callable($func))
        {
            if (
is_string($func))
            {
               
$func = create_function('', $func);
            }
            else
            {
                throw new
InvalidArgumentException();
            }
        }
       
       
self::$timers[++self::$numTimers] = array(
                                                   
'time' => self::microtime() + $microseconds,
                                                   
'function' => $func,
                                                );
       
        return
self::$numTimers;
    }
   
   
/**
     * Add a function to the be executed every ($microseconds) microsecond
     *
     * @static
     *
     * @param callable | string $func
     * @param integer $microseconds - remember microseconds, not miliseconds
     *
     * @return integer
     */
   
public static function setInterval ($func, $microseconds)
    {
        if (!
is_callable($func))
        {
            if (
is_string($func))
            {
               
$func = create_function('', $func);
            }
            else
            {
                throw new
InvalidArgumentException();
            }
        }
       
       
self::$intervals[++self::$numIntervals] = array(
                                                           
'time' => self::microtime() + $microseconds,
                                                           
'function' => $func,
                                                           
'microseconds' => $microseconds,
                                                        );
       
        return
self::$numIntervals;
    }
   
   
/**
     * Remove a timeout function from the stack
     *
     * @static
     *
     * @param integer $timer
     *
     * @return boolean
     */
   
public static function clearTimeout ($timer)
    {
        if (isset(
self::$timers[$timer]))
        {
            unset(
self::$timers[$timer]);
            return
true;
        }
       
        return
false;
    }
   
   
/**
     * Remove an interval function from the stack
     *
     * @static
     *
     * @param integer $interval
     *
     * @return boolean
     */
   
public static function clearInterval ($interval)
    {
        if (isset(
self::$intervals[$interval]))
        {
            unset(
self::$intervals[$interval]);
            return
true;
        }
       
        return
false;
    }
}

/**
 * Register these methods in order to perform polling a specific intervals
 * that are set by the user
 */
register_tick_function(array('Timers','tick'));
register_shutdown_function(array('Timers','shutdown'));

?>