note 104062 deleted from function.register-shutdown-function by danbrown

From: Date: Fri, 20 May 2011 14:28:47 +0000
Subject: note 104062 deleted from function.register-shutdown-function by danbrown
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-179909@lists.php.net to get a copy of this message
Note Submitter: dcz at phpbb-seo dot com ---- I found that emanueledelgrande's shutdownScheduler class was quite a nice approach. Here another version of the same concept with a priority feature. I also though that turning it to static would be more appropriate, and also handier to use (it can be used anywhere without global or get instance this way). <?php /** * shutdown * Author : dcz * inspired from emanueledelgrande's shutdownScheduler : http://www.php.net/register_shutdown_function#100000 * Feel free to use as you wish at your own risk ;-) **/ class shutdown { private static $callbacks = array(); private static $priorities = array(); private static $inited = false; /** * void init() **/ private static function init() { if (!self::$inited) { self::$inited = true; register_shutdown_function('shutdown::call'); } } /** * void set_priotity(string $key, int $priority) **/ public static function set_priotity($key, $priority) { self::$priorities[(string) $key] = (int) $priority; } /** * bool is_registered(string $key) **/ public static function is_registered($key) { return isset(self::$callbacks[$key]); } /** * bool register() **/ public static function register() { if (!self::$inited) { self::init(); } $callback = func_get_args(); if (empty($callback)) { return false; } if (!is_callable($callback[0])) { return false; } if (is_array($callback[0])) { $key = get_class($callback[0][0]) . '->' . $callback[0][1]; } else { $key = $callback[0]; } self::$callbacks[$key] = $callback; return true; } /** * void call() **/ public static function call() { $_callbacks = array(); foreach (self::$callbacks as $key => & $arguments) { if (isset(self::$priorities[$key])) { $_callbacks[self::$priorities[$key]][$key] = & $arguments; } else { $_callbacks[0][$key] = & $arguments; } } krsort($_callbacks); foreach ($_callbacks as $priority => & $calls) { foreach ($calls as $key => & $args) { $callback = array_shift($args); call_user_func_array($callback, $args); } } } } ?> Usage : <?php class statictest { public static function test($str) { echo $str . '<br/>'; } public static function test2($str) { echo $str . '<br/>'; } } class objtest { function __construct() { shutdown::register(array(&$this, 'test3'), 'Calling objtest->test3'); } public function test($str) { echo $str . '<br/>'; } public function test2($str) { echo $str . '<br/>'; } public function test3($str) { echo $str . '<br/>'; } } function test($str) { echo $str . '<br/>'; } function test2($str) { echo $str . '<br/>'; } $obj = new objtest(); // will register our first "event" // regular registering, registered events triggered in the order they where created // you could want to test the result to know if the registration actually went through shutdown::register('statictest::test', 'Calling statictest::test'); shutdown::register('statictest::test2', 'Calling statictest::test2'); shutdown::register(array(&$obj, 'test'), 'Calling objtest->test'); shutdown::register(array(&$obj, 'test2'), 'Calling objtest->test2'); shutdown::register('test', 'Calling test'); shutdown::register('test2', 'Calling test2'); // we can overwrite shutdown::register(array(&$obj, 'test'), 'Overwritten objtest->test call, original trigger order kept'); // we can also make sure we do not overwrite if necessary if (!shutdown::is_registered('test2')) { shutdown::register('test2', 'Overwrite test2 call if not already registered'); } // set some priorities, keys are using original notation for class names (from get_class in php5), // chosen convention should be obvious to understand // greatest priority will be triggered first shutdown::set_priotity('statictest::test2', 10); shutdown::set_priotity('objtest->test2', 10); shutdown::set_priotity('test2', 11); shutdown::set_priotity('statictest::test', -10); exit; ?> Would display : Calling test2 Calling statictest::test2 Calling objtest->test2 Calling objtest->test3 Overwritten objtest->test call, original trigger order kept Calling test Calling statictest::test

« previous php.notes (#179909) next »