note 125304 deleted from function.fastcgi-finish-request by salathe

From: Date: Thu, 27 Aug 2020 07:58:23 +0000
Subject: note 125304 deleted from function.fastcgi-finish-request by salathe
References: 1  Groups: php.notes 
Request: Send a blank email to php-notes+get-215030@lists.php.net to get a copy of this message
Note Submitter: marcelotpcruz at gmail dot com ---- My previous code was not clean and fully tested, there was some workaround needed to make that workable that I didn't post later. But here comes a tested and nice class I wrote after searching a bit more about it that doesn't close the connection, which according the information I looked around can affect keep alive. Due credits to: https://stackoverflow.com/a/26892012 <?php /** * Output class * * Perform early "response flush" for users who can't rely on php fastcgi_finish_request. */ class Output { private static $length_sent = 0; private static bool $done = false; const MIN_LENGTH_2_CLOSE_CONNECTION = 4 * 1024; static function handle() { if (!ob_start(__CLASS__ . "::ob_chunked_gzhandler")) self::startException(); self::sendHeader(); register_shutdown_function(__CLASS__ . "::close"); } static function sendHeader() { // if (!headers_sent()) // throw new Exception("These should be sent!"); header('Transfer-Encoding: chunked'); } static function startException() { throw new Exception("Ob start can't be started..."); } /** * close — Flushes all response data to the client * * This function flushes all response data to the client and finishes the request. * This allows for time consuming tasks to be performed without leaving the connection to the client open. * * control method must be called first any output is sent for this method to work. * * @return void */ static function close() { if (self::$done) return; ignore_user_abort(true); if (session_id()) session_write_close(); self::$done = true; if (ob_get_length()) ob_flush(); ob_end_clean(); self::$length_sent += 5; // Terminating Chunk echo "\x30\r\n\r\n"; if (self::$length_sent < self::MIN_LENGTH_2_CLOSE_CONNECTION) echo str_pad("", self::MIN_LENGTH_2_CLOSE_CONNECTION - self::$length_sent, "\r\n"); ob_flush(); flush(); } static function ob_chunked_gzhandler($buffer, $phase) { $buffer = ob_gzhandler($buffer, $phase); $length = strlen($buffer); self::$length_sent += $length + 2; return dechex($length) . "\r\n$buffer\r\n"; } } /** * order of output and session_start doesn't matter * Might as well be. * session_start(); * Output::handle(); */ Output::handle(); session_start(); var_dump($_SESSION); $_SESSION["kk"] = "dfdfdf"; $_SESSION["xkcd"] = "dfdfdf"; echo "1"; echo "2\n"; Output::close(); sleep(10); echo "Message user is not seeing..."; file_put_contents(__DIR__ . DIRECTORY_SEPARATOR . 'bla.txt', "Yeah, A fully working sample.");

« previous php.notes (#215030) next »