Fread is much slower to load than readfile

I am serving downloads from a url to my users via a PHP script. On use, readfile()

I get the maximum download speed my connection can support (about 2.5 MB / s), however, when I use the route fopen, fread, fclose

, the download speed is very, very slow (about 1-2 KB / s).

Here's my code:

header('Content-Description: File Transfer');
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename=' . $filename);
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma: public');
header('Content-Length: ' . $filesize);
ob_clean();
flush();

$file = fopen($url, 'rb');

while(!feof($file)) {
    echo fread($file, 2014);
}

      

and the readfile code is simple readfile($link);

.

I can't just use the function readfile()

for two reasons: one - I want to limit the download speed of users (which I can do with fread

only reading out so much data), and I also want to track how much the user is downloading (I can do this with readfile()

, but he does not include partial downloads).

Does anyone know why this might be happening or how I can fix it? As far as I know, readfile()

this is just a wrapper for fopen, fread and fclose

so I don't understand what's going wrong.

Edit: ended up with cURL for this.

$curl = curl_init();
$options = array(
    CURLOPT_URL => $rdLink,
    CURLOPT_FAILONERROR => true,
    CURLOPT_BINARYTRANSFER => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_WRITEFUNCTION => 'readResponse'
);
curl_setopt_array($curl, $options);

if(!curl_exec($curl)) {
    header('Location: http://whatever.com');
    exit;
}
curl_close($curl);

function readResponse($ch, $data) {
    $length = mb_strlen($data, '8bit');

    echo $data;

    return $length;
}

      

+3


source to share


3 answers


Use stream_context_create () and stream_get_contents ()

$context = stream_context_create();
$file = fopen($url, 'rb', FALSE, $context);
while(!feof($file))
{
    //usleep(1000000);
    echo stream_get_contents($file, 2014);
}

      



You can also try to increase the file read length and insert usleep () to slow down execution. Apparently thread functions are still recommended for fread for the latest PHP version. You might also want to add @ in front of fread () or stream_get_contents () to suppress any errors, at least in production. Without it and a bit of bad luck and you have a corrupted file.

+2


source


It could be buffering (or maybe rate limiting) somewhere in PHP or Apache. Try to change:

while(!feof($file)) {
   echo fread($file, 2014);
}

      

To:



while(!feof($file)) {
   $s=fread($file, 2014);
   if($s===false)break;  //Crude
   echo $s;
   @ob_flush();@flush();
}

      

(The prefix @

is that they might complain about empty buffers.)

As mr.freshwater said, you must have error checking on your call fread

, so I added something basic above.

0


source


The reason is 2014. OS receives 4096 bytes of data very quickly, while others. But if you are writing 2014, then the OS is trying to read the data from the file by one byte in order to calculate it. That's why it took so long. Change from 2014 to 4096

0


source







All Articles