Login   Register  
PHP Classes
elePHPant
Icontem

File: Timers.class.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  Classes of Sam Shull  >  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: 5 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'));

?>