<?php // class deferer // // This class can be used to defer action until after the user connection is closed // Initiallize the script with deferer::initialize() prior to any outpub // register actions to be done by using registerAction. // // Example: deferer::initialize(); registerAction(function() use($userid, $useremail) {sendUserEmail($userid, $useremail);}); // // The above example will result in the user's browser closing the connection // before the sendUserEmail is run which will cause faster client page loading // // If you have trouble with database connections closing try initializing // with registerShutdown = false and manually calling processActions at the end of your script. // // Hint: If something needs to be registered toward the end (like closing connections) but // you want to queue it in your main application script try it like this // deferer::registerAction(function() { deferer::registerAction(function() {closeSqlConnections();}); }); // // License MIT class deferer { protected static $actions = array(); protected static $initialized = false;
/** * Initialize the deferer (must be called before content is outputed) * * @param bool $registerShutdown */ public static function initialize($registerShutdown=true) { if (static::$initialized) { return; }
static::$initialized = true;
ob_start();
if ($registerShutdown) { register_shutdown_function("deferer::processActions"); } }
/** * Register an action to be done after client connection is closed. * * @param closure $action */ public static function registerAction(closure $action) { static::$actions[] = $action; }
/** * Attempt to close the user client agent. */ protected static function connectionCloser() { while (ob_get_level() > 2) ob_end_flush(); // flush all output buffers into the default level
$length = ob_get_length(); $html = ob_get_clean();
header("Content-Length: ".$length); header("Connection: Close");
ob_flush(); // headers echo $html; flush(); }
/** * Process all the queued actions. */ public static function processActions() { if (static::$initialized) { static::connectionCloser(); }
foreach (static::$actions as $closure) { call_user_func($closure); } } }
|