/** * @param array $configuration * @throws \Zend\Cache\Exception\InvalidArgumentException * @throws \Zend\Cache\Exception\RuntimeException */ public function __construct(array $configuration) { if (!isset($configuration['adapter'])) { $configuration['adapter'] = 'Filesystem'; } if (!isset($configuration['adapterOptions'])) { $configuration['adapterOptions'] = []; } $cache = StorageFactory::factory(['adapter' => ['name' => $configuration['adapter'], 'options' => $configuration['adapterOptions']]]); $options = $cache->getOptions(); $options->setNamespace('Shariff'); $options->setTtl($configuration['ttl']); if ($options instanceof FilesystemOptions) { $options->setCacheDir(isset($configuration['cacheDir']) ? $configuration['cacheDir'] : sys_get_temp_dir()); } if ($cache instanceof ClearExpiredInterface) { if (function_exists('register_postsend_function')) { // for hhvm installations: executing after response / session close register_postsend_function(function () use($cache) { $cache->clearExpired(); }); } else { // default $cache->clearExpired(); } } $this->cache = $cache; }
/** * Single shot defer handeler install */ protected static function install_shutdown() { if (static::$inited_shutdown) { return; } // Disable time limit set_time_limit(0); // HHVM support if (function_exists('register_postsend_function')) { register_postsend_function(function () { Event::trigger('core.shutdown'); }); } else { if (function_exists('fastcgi_finish_request')) { register_shutdown_function(function () { fastcgi_finish_request(); Event::trigger('core.shutdown'); }); } else { register_shutdown_function(function () { Event::trigger('core.shutdown'); }); } } static::$inited_shutdown = true; }
<?php ini_set('memory_limit', '1M'); function foo() { $x = array(); while (true) { $x[] = str_repeat("asd", 100); } } function go() { echo "hi\n"; foo(); } register_postsend_function('go'); foo();
/** * This function does work that can be done *after* the * user gets the HTTP response so they don't block on it * * This manages deferred updates, job insertion, * final commit, and the logging of profiling data * * @param string $mode Use 'fast' to always skip job running * @since 1.26 */ public function doPostOutputShutdown($mode = 'normal') { $timing = $this->context->getTiming(); $timing->mark('requestShutdown'); // Show visible profiling data if enabled (which cannot be post-send) Profiler::instance()->logDataPageOutputOnly(); $callback = function () use($mode) { try { $this->restInPeace($mode); } catch (Exception $e) { MWExceptionHandler::handleException($e); } }; // Defer everything else... if (function_exists('register_postsend_function')) { // https://github.com/facebook/hhvm/issues/1230 register_postsend_function($callback); } else { if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } else { // Either all DB and deferred updates should happen or none. // The latter should not be cancelled due to client disconnect. ignore_user_abort(true); } $callback(); } }
/** * This function does work that can be done *after* the * user gets the HTTP response so they don't block on it * * @param string $mode Use 'fast' to always skip job running * @since 1.26 */ public function doPostOutputShutdown($mode = 'normal') { // Show profiling data if enabled Profiler::instance()->logDataPageOutputOnly(); $that = $this; $callback = function () use($that, $mode) { try { // Assure deferred updates are not in the main transaction wfGetLBFactory()->commitMasterChanges(); // Run jobs occasionally, if enabled if ($mode === 'normal') { $that->triggerJobs(); } // Do deferred updates and job insertion and final commit $that->restInPeace(); } catch (Exception $e) { MWExceptionHandler::handleException($e); } }; if (function_exists('register_postsend_function')) { // https://github.com/facebook/hhvm/issues/1230 register_postsend_function($callback); } else { if (function_exists('fastcgi_finish_request')) { fastcgi_finish_request(); } else { // Either all DB and deferred updates should happen or none. // The later should not be cancelled due to client disconnect. ignore_user_abort(true); } $callback(); } }
function test() { var_dump('function'); } class Test { function handleInstance() { var_dump('Method - instance'); } static function handleStatic() { var_dump('Method - static'); } } register_postsend_function(__NAMESPACE__ . '\\test'); register_postsend_function([new Test(), 'handleInstance']); register_postsend_function([__NAMESPACE__ . '\\Test', 'handleStatic']); register_postsend_function(function () { var_dump('Lambda'); }); register_postsend_function(function () { var_dump(func_get_args()); }, 123); register_postsend_function(function () { var_dump(func_get_args()); }, ['foo' => 'bar'], 123); register_postsend_function(function () { var_dump(func_get_args()); }, (object) ['foo' => 'bar']);
<?php var_dump('before reg'); register_postsend_function(function () { var_dump('first, start'); register_postsend_function(function () { var_dump('second, start'); register_postsend_function(function () { var_dump('third, start'); register_postsend_function(function () { var_dump('fourth, start'); }); var_dump('third, end'); }); var_dump('second, end'); }); var_dump('first, end'); }); var_dump('after reg');