1

How to send the header to the client before execute the php scripts ?

My script take many time to finish and the client don't receive anything through this period.

<?

header("HTTP/1.1 200 OK");
header("Date: Thu, 23 Jun 2011 10:16:31 GMT");
header("Content-Type: application/octet-stream");
header("Content-Length: 12275768");
header("Accept-Ranges: bytes");
header('Content-Disposition: attachment; filename="Untitled-1.bmp"');
header("Content-Transfer-Encoding: binary");
header("Connection: close");

//Send headers now

//because my php script take many time to finish
//because it downloads a file from a remote server

.
.
.

?>
faressoft
  • 19,053
  • 44
  • 104
  • 146
  • If you have the possibility, you should try to execute the time consuming script in CLI and manage its execution via a database table, that way you can leave the user free to browse the website while the script finnishes processing the info. – Catalin Jun 23 '11 at 10:40
  • What exactly are you doing that takes this long? – Gumbo Jun 23 '11 at 10:46
  • @Gumbo : My script download a file from remote server and return the file to my client. I am using passthru("curl ...") to do that. – faressoft Jun 23 '11 at 10:49
  • @faressoft: Ok, so you’re already passing the data through while receiving it. But did you also try a different way like `fopen` and `fpassthru` or a chunked response? – Gumbo Jun 23 '11 at 10:51
  • @Gumbo : I can't use fopen because I wan't to use cookies and ranges with curl. – faressoft Jun 23 '11 at 11:16
  • @faressoft: You could use a stream context. – Gumbo Jun 23 '11 at 11:22
  • @Gumbo : http://php.net/manual/en/function.stream-context-create.php something like example 1 ? Does it help me more than passthru ? – faressoft Jun 23 '11 at 11:31
  • @faressoft: You could try that with a [chunked encoding](http://tools.ietf.org/html/rfc2616#section-3.6.1). I’ll try to mockup an example. – Gumbo Jun 23 '11 at 12:31

4 Answers4

1

I’m not sure how passthru works and if the command’s output is buffered somehow. But here’s another example using fopen, a streaming context for the request header fields and the chunked transfer coding with an explicit flush:

header("HTTP/1.1 200 OK");
header("Date: Thu, 23 Jun 2011 10:16:31 GMT");
header("Content-Type: application/octet-stream");
header("Accept-Ranges: bytes");
header('Content-Disposition: attachment; filename="Untitled-1.bmp"');
header('Content-Transfer-Encoding: chunked');
header("Connection: close");

$opts = array(
  'http'=>array(
    'method'=>"GET",
    'header'=>"Accept-language: en\r\n" .
              "Cookie: foo=bar\r\n"
  )
);
$context = stream_context_create($opts);
$fp = fopen('http://www.example.com', 'r', false, $context);
while (($buffer = fread($fp, 512)) !== false) {
    echo sprintf("%X", strlen($buffer)), "\r\n", $buffer, "\r\n";
    flush();
}
echo "0\r\n\r\n";
flush();

Make sure not to use ob_start or any other output buffering.

Community
  • 1
  • 1
Gumbo
  • 643,351
  • 109
  • 780
  • 844
0

ob_flush() function flushes immediately output buffer. Are you looking for something like this?

Adi
  • 5,089
  • 6
  • 33
  • 47
heximal
  • 10,327
  • 5
  • 46
  • 69
  • Yes, I put ob_flush() after the headers but nothing changed – faressoft Jun 23 '11 at 10:28
  • and what must happend then? you may do? for example, echo (' Please wait, your request is being processed');, and client will see it in its browser. what affect are you trying to get? – heximal Jun 23 '11 at 10:32
0

Use ob_start() and output something, then ob_flush; then output some more, then ob_flush again.

bfavaretto
  • 71,580
  • 16
  • 111
  • 150
max4ever
  • 11,909
  • 13
  • 77
  • 115
0

In your php script create headers, start writing html code, then flush, and continue creating rest of the HTML.

Aziz Shaikh
  • 16,245
  • 11
  • 62
  • 79