Many thanks to Richard and Skippy.
Skippy: Your suggestion to set non-blocking mode (stream_set_blocking) was the magic key to success.
Here is the code I ended up with, I left some test stuff included so anyone who may need it has a good start.
>$fp= fopen($file, 'rb' ); if (!$fp) {die ("Failed to open $file, errors: $errstr ($errno)<br>\n"); }//end if
stream_set_blocking($fp, FALSE ); $html= ''; $chunk= ''; $start= time(); while (!feof($fp)){ sleep($interval); $chunk= fread($fp, 10000); //chunks, packets are limited anyhow $length= strlen($chunk); if($length)== 0){echo "<div style=\"color:blue\">Read zero bytes</div>";} $html .= $chunk; echo "<div>At " . date("h:s") . ">> $length bytes read</div>"; ob_flush(); if (time() - $start > $timelimit){echo("<div>style= \"color:red\">Timeout!</div>\n"); break;} }//end while
Putting the sleep() first thing helps everything get started better. Seems as if fread() needs a little time after fopen().
ob_flush() is neat. It forces the client browser to render progress. I've always been told you can't make a progress bar or list with php. Well here it is, at least it works with IE6 and Mozilla.
Skippy wrote:
Quoting Al <news@xxxxxxxxxxxxx>:
Darn, I left out an important function, the fread(). Code snip should be: $fp= fopen("http://www.anything.com/foo.html, 'rb'); if(!fp) {do something different} stream_set_timeout($fp, 2); $contents= fread($fp, 200000); $status= stream_get_meta_data($fp); if($status[timed_out] {do something};
It appears to me there is a basic logic problem. The script must get past the fread() function before it gets to the stream_get_meta_data($fp). But, it hangs up on fread() and the script times out.
Set the stream to non-blocking mode (stream_set_blocking). Now all read functions will return instantly, regardless if any data came through. You can test whether you got back anything by checking the returned data. If you now read from the non-blocked stream in a cycle, you will have no "dead" times and you will always retain control. Only now can you rely on comparing time() with a control value set before entering the cycle and decide to abort if a number of seconds has passed.
stream_set_timeout() will be pretty much superfluous at this point and may even hinder your reading from the stream.
Important tip: in a non-blocking cycle you MUST have an usleep() somewhere. Otherwise that cycle will consume 100% CPU while it runs. An usleep(1000) will suffice, adjust as needed.
-- PHP General Mailing List (http://www.php.net/) To unsubscribe, visit: http://www.php.net/unsub.php