Forum Moderators: coopster

Message Too Old, No Replies

fread really slow retrieving remote image

         

dublinmike

10:14 am on Oct 2, 2006 (gmt 0)

10+ Year Member



Hi,

I was wondering if anybody out there might have some insight into this. I have the following function to download/transfer an image file stored on a remote server to my own server:

function download($file_source, $file_target)
{
$rh = fopen($file_source, 'rb');
$wh = fopen($file_target, 'wb');
if ($rh===false ¦¦ $wh===false)
{
return true;
}
while (!feof($rh))
{
if (fwrite($wh, fread($rh, 1024)) === FALSE)
{
return true;
}
}
fclose($rh);
fclose($wh);
return false;
}

This function works fine except it is painfully slow. I'm calling it twice in my main file to download a 20k image and a 3k image and without fail it takes longer than 3 minutes to execute.

I've read that file_get_contents is the preferred way of reading a file into a string yet (this is where it gets strange) file_get_contents corrupts the larger image (memory issue perhaps?). Also, if I increase the number of bytes I read in per chunk in the above code to 8192 for example, the image again becomes corrupted.

I've been scratching my head for a while now on this and have drawn a complete blank. Any suggestions would be very much welcomed. Thanks in advance.

eelixduppy

8:59 pm on Oct 2, 2006 (gmt 0)



I believe it's slow because of the nature of what it's actually doing. Have you considered using FTP [php.net] for transfering these remote files?

dublinmike

4:53 pm on Oct 3, 2006 (gmt 0)

10+ Year Member



Hi,

Thanks for the reply. I don't actually have FTP access to the remote server, it's an image that comes with syndicated news content that's available only over HTTP.

Apparently, fread is inherently slow and I've had a look at using cURL or file_get_contents but without any success. Any idea why file_get_contents would return corrupted data (or return different data to an fread)?

If I could find some information on how file_get_contents works internally (i.e. how it reads data differently to fread), that would be really helpful but info on this function is pretty thin on the ground.

coopster

9:43 pm on Oct 3, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member



You'll have to pull the PHP source code down and look through the internals to get any more detail on the command other that what is printed in the manual.

What server is this? IIS?
Are the images coming over SSL?
Which version of PHP?

dublinmike

10:50 pm on Oct 3, 2006 (gmt 0)

10+ Year Member



Hi coopster,

Thanks for the response. In response to your questions: No SSL, image is on IIS server, my server is Apache running PHP 4.4.4. Good suggestion about having a look at the source. I'm not too good at C but the difference in how file_get_contents and fread get the data appears to be in the following lines:

fread:
php_stream_read(stream, Z_STRVAL_P(return_value), len)

file_get_contents:
php_stream_copy_to_mem(stream, &contents, PHP_STREAM_COPY_ALL, 0)

So, it looks as though in file_get_contents, it tries to copy the entire stream contents directly to memory whereas fread (in my original function) just tries 1kb at a time. I think my PHP memory limit is set to the default of 8M so why would it not get all the image data if it's only 20kb?

coopster

1:16 pm on Oct 5, 2006 (gmt 0)

WebmasterWorld Administrator 10+ Year Member




image is on IIS server

So you are reading this via HTTP from a different server altogether -- have you checked to make sure this isn't your bottleneck, the other server and the bandwidth delay? Try reading directly from you own filesystem first, see if you have the same issues.