views:

535

answers:

7

I am using ob_start()/ob_flush() to, hopefully, give me some progress during a long import operation.

Here is a simple outline of what I'm doing:

<?php
ob_start ();

echo "Connecting to download Inventory file.<br>";
$conn = ftp_connect($ftp_site) or die("Could not connect");

echo "Logging into site download Inventory file.<br>";
ftp_login($conn,$ftp_username,$ftp_password) or die("Bad login credentials for ". $ftp_site);

echo "Changing directory on download Inventory file.<br>";
ftp_chdir($conn,"INV") or die("could not change directory to INV");

//      connection, local, remote, type, resume
$localname = "INV"."_".date("m")."_".date('d').".csv";
echo "Downloading Inventory file to:".$localname."<br>";

ob_flush();
flush();
sleep(5);

if (ftp_get($conn,$localname,"INV.csv",FTP_ASCII)) 
{
    echo "New Inventory File Downloaded<br>";
    $datapath = $localname;
    ftp_close($conn);
} else {
    ftp_close($conn);
    die("There was a problem downloading the Inventory file.");      
}
ob_flush();
flush();
sleep(5);

$csvfile = fopen($datapath, "r"); // open csv file
$x = 1;
// skip the header line
$line = fgetcsv($csvfile);
$y = (feof($csvfile) ? 2 : 5);
while ((!$debug) ? (!feof($csvfile)) : $x <= $y) {
    $x++;
    $line = fgetcsv($csvfile);
    // do a lot of import stuff here with $line
    ob_flush();
    flush();
    sleep(1);
}

fclose($csvfile); // important: close the file
ob_end_clean();

However, nothing is being output to the screen at all.

I know the data file is getting downloaded because I watch the directory where it is being placed.

I also know that the import is happening, meaning that it is in the while loop, because I can monitor the DB and records are being inserted.

Any ideas as to why I am not getting output to the screen?

+1  A: 

This is probably because:

  • the browser isn't displaying the page until it receives all of it
  • the web server running PHP isn't transmitting the data to the client until it receives all of it (probably more likely)
George Edison
A: 

Ob_end_clean() discards the contents of the current output buffer and turns off the buffering. You should use ob_end_flush() instead.

fireweasel
He's calling `ob_flush()` throughout the script though
Michael Mrozek
+2  A: 

You also need to check the PHP settings

some installs default to 4096, some default to off

output_buffering = Off
output_buffering = 4096

agreed with George but do check the above settings

Geek Num 88
<egg on face>Well, looky here, I thought output_buffering = Off in php.ini but I was wrong. Looked at the wrong line.</egg on face>
MB34
@MB34 You should mark this answer right if it solved your problem; there's a checkmark to the left you can click
Michael Mrozek
+2  A: 

Make sure that your output buffering doesn't start automatically. Run:

print ob_get_level ();

before ob_start (); if will will see something else then 0 you've got the answer.

Piotr Pankowski
A: 

It's possible that your webserver is doing its own buffering. Probably with something like mod_gzip.

Here is some very simple test code:

<?php
echo 'starting...<br/>';
for($i = 0; $i < 5; $i++) {
  print "$i<br/>";
  flush();
  sleep(2);
}
print 'DONE!<br/>';

If it takes 10 seconds for that page to load, rather than seeing a new line every 2 seconds, then it means that it is being cached by your webserver. For what you are trying to do, there is no need to use ob_start and ob_flush. Just call flush whenever you want to force the content to the browser. However, like I mentioned, if the webserver is waiting for the content to complete before sending, then that won't do anything for you.

Edit: Another possibility is that you're viewing the page from behind a corporate or ISP proxy/firewall that waits for the whole page before serving it (so that it can scan it to see if it looks like pornography, for example).

Kip
After setting output_buffering =Off, this worked like it should.
MB34
A: 

[egg on face]

Well, looky here, I thought output_buffering = Off in php.ini but I was wrong. Looked at the wrong line.

[/egg on face]

MB34
A: 

not work ob_start() when we are use header() function

mohit