note 96951 modified in function.fwrite by danbrown
| From: | danbrown@php.net | Date: | Wed, 24 Mar 2010 22:10:22 +0000 |
| Subject: | note 96951 modified in function.fwrite by danbrown | ||
| References: | 1 | Groups: | php.notes |
| Request: | Send a blank email to php-notes+get-167368@lists.php.net to get a copy of this message | ||
After having problems with fwrite() returning 0 in cases where one would fully expect a return value
of false, I took a look at the source code for php's fwrite() itself. The function will only
return false if you pass in invalid arguments. Any other error, just as a broken pipe or closed
connection, will result in a return value of less than strlen($string), in most cases 0.
Therefore, looping with repeated calls to fwrite() until the sum of number of bytes written equals
the strlen() of the full value or expecting false on error will result in an infinite loop if the
connection is lost.
This means the example fwrite_stream() code from the docs, as well as all the "helper"
functions posted by others in the comments are all broken. You *must* check for a return value of 0
and either abort immediately or track a maximum number of retries.
Below is the example from the docs. This code is BAD, as a broken pipe will result in fwrite()
infinitely looping with a return value of 0. Since the loop only breaks if fwrite() returns false or
successfully writes all bytes, an infinite loop will occur on failure.
<?php
// BROKEN function - infinite loop when fwrite() returns 0s
function fwrite_stream($fp, $string) {
for ($written = 0; $written < strlen($string); $written += $fwrite) {
$fwrite = fwrite($fp, substr($string, $written));
if ($fwrite === false) {
return $written;
}
}
return $written;
}
?>
--was--
After having problems with fwrite() returning 0 in cases where one would fully expect a return value
of false, I took a look at the source code for php's fwrite() itself. The function will only
return false if you pass in invalid arguments. Any other error, just as a broken pipe or closed
connection, will result in a return value of less than strlen($string), in most cases 0.
Therefore, looping with repeated calls to fwrite() until the sum of number of bytes written equals
the strlen() of the full value or expecting false on error will result in an infinite loop if the
connection is lost.
This means the example fwrite_stream() code from the docs, as well as all the "helper"
functions posted by others in the comments are all broken. You *must* check for a return value of 0
and either abort immediately or track a maximum number of retries.
Below is the example from the docs. This code is BAD, as a broken pipe will result in fwrite()
infinitely looping with a return value of 0. Since the loop only breaks if fwrite() returns false or
successfully writes all bytes, an infinite loop will occur on failure.
<code>
<?php
// BROKEN function - infinite loop when fwrite() returns 0s
function fwrite_stream($fp, $string) {
for ($written = 0; $written < strlen($string); $written += $fwrite) {
$fwrite = fwrite($fp, substr($string, $written));
if ($fwrite === false) {
return $written;
}
}
return $written;
}
?>
</code>
http://php.net/manual/en/function.fwrite.php