php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Doc Bug #23874 fread() exits prematurely on files opened over HTTP
Submitted: 2003-05-29 12:16 UTC Modified: 2003-05-29 15:16 UTC
Votes:2
Avg. Score:5.0 ± 0.0
Reproduced:1 of 1 (100.0%)
Same Version:1 (100.0%)
Same OS:1 (100.0%)
From: kier at vbulletin dot com Assigned: wez (profile)
Status: Closed Package: Documentation problem
PHP Version: 4.3.2 OS: Redhat Linux 8.0
Private report: No CVE-ID: None
 [2003-05-29 12:16 UTC] kier at vbulletin dot com
After switching from PHP 4.3.2 RC2 to PHP 4.3.2 RC4 I noticed that a lot of my scripts failed to properly open the files they were asked to...

Here is an example script that works fine under PHP 4.3.2 RC2 but breaks under 4.3.2 RC4 and later. I have not tried 4.3.2 RC3 so I can't say whether the problem was introduced at the RC3 or RC4 stage. Nonetheless, the problem still exists in PHP 4.3.2 Final.

<?php

$path = 'http://www.domain.com/some/large/page.html';

$fp = fopen($path, 'r');
$contents = fread($fp, 99999999);

echo '<pre>' . htmlspecialchars($contents) . '</pre>';

?>

This will output the HTML source of the page referenced in $path, but under recent versions of PHP 4.3.2 the contents is truncated, having not reached the end of the file.

It is worth noting that using

$contents = '';
while (!feof($fp))
{
    $contents .= fgets($fp, 100);
}

does not exhibit the fread() truncation problem, and neither does using fread() on LOCAL files. The problem seems isolated to opening remote files over HTTP with fread();

I have verified this bug on several servers under different PHP configurations.

Patches

Add a Patch

Pull Requests

Add a Pull Request

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2003-05-29 13:23 UTC] iliaa@php.net
Thank you for taking the time to write to us, but this is not
a bug. Please double-check the documentation available at
http://www.php.net/manual/ and the instructions on how to report
a bug at http://bugs.php.net/how-to-report.php

You should be doing:

$contents = '';
while (($data = fread($fp, 99999999))) {
$contents .= $data;
}

A single fread() could get interupted by a signal and thus not fetch all the data. By having the read code in a loop you protect yourself against such a problem.

Better yet, use file_get_contents() to fetch the entire file in one go. This function was introduced in PHP 4.3.0.
 [2003-05-29 13:40 UTC] kier at vbulletin dot com
Thanks, I will make the appropriate changes to my code to reflect this.

However, is it possible that the online documentation is now out of date or misleading? To quote:

"fread() reads up to length bytes from the file pointer referenced by handle. Reading stops when length bytes have been read or EOF (end of file) reached, whichever comes first."

This is then followed by a code example that doesn't use fread() in a while() loop. Perhaps the manual should be updated to note potential problems when using fread() on remote resources?
 [2003-05-29 14:47 UTC] wez@php.net
This non-greedy read behaviour has always been the default, except in PHP 4.3.0 and 4.3.1 where it was broken and performed greedy reads instead.

You should always be prepared to read chunks when working with network streams and also FIFO streams (from popen() and proc_open()).

And yes, the documentation should be updated; I will do this shortly.
 [2003-05-29 15:00 UTC] nicos@php.net
Changing this to a documentation problem.
 [2003-05-29 15:16 UTC] wez@php.net
nicos: butt out; I've already committed the docs.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sun Jun 02 10:01:32 2024 UTC