Skip to content
Advertisement

Compress a manually closed connection AND continue processing

  • I’ve managed to close a PHP connection early and continue processing.
  • I’ve managed to send a compressed response to a client.
  • I have not managed to do both at the same time.

How do send a compressed response and continue processing?

Currently my somewhat minimal test case compresses the server response though it doesn’t close the connection:

<?php
ob_start();
echo '<style type="text/css">* {background-color: #000; color: #fff;}</style>';
echo '<p>Testing response: '.time().'.</p>';
$c = ob_get_contents();
ob_end_clean();

ob_start('ob_gzhandler');
echo $c;
$size = ob_get_length();
ob_end_flush();


// Set the content length of the response.
header("Content-Length: {$size}");

// Close the connection.
header('Connection: close');

// Flush all output.
ob_end_flush();

// Close current session (if it exists).
if (session_id()) {session_write_close();}

sleep(2);
file_put_contents('test.txt', 'testing: '.time().'; size: '.$size);
?>

Advertisement

Answer

I managed to reduce the code in thanks to a comment by Rush on the ob_get_length documentation page. All three flush commands are required, commenting out any of them results in the page not loading until after sleep(4). I tested this to ensure that the connection closed in the browser, was compressed and then switched over to my file manager to see the file created a few seconds later.

<?php
ob_start();
ob_start('ob_gzhandler');

// Send your response.
echo '<style>* {background-color: #000; color: #fff;}</style>';
echo '<p>Testing response: '.time().'.</p>';

// The ob_gzhandler one
ob_end_flush();

header('Content-Length: '.ob_get_length());

// The main one
ob_end_flush();
ob_flush();
flush();

// Close current session (if it exists).
if (session_id()) {session_write_close();}

sleep(4);
file_put_contents('test.txt', 'testing: '.time().'; size: '.$size);
?>
User contributions licensed under: CC BY-SA
4 People found this is helpful
Advertisement